; -*-MIDAS-*-
;;; Copyright (c) 1999 Massachusetts Institute of Technology
;;;
;;; This program is free software; you can redistribute it and/or
;;; modify it under the terms of the GNU General Public License as
;;; published by the Free Software Foundation; either version 3 of the
;;; License, or (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;; General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program; if not, see https://gnu.org/licenses or
;;; write to:
;;;  Free Software Foundatiom, Inc.
;;;  51 Franklin St, Fifth Floor
;;;  Boston, MA 02110-1301
;;;  USA


SUBTTL DEMON JOB INTERFACE ROUTINES
	;GIVE STUFF TO DEMON JOB RUNNING IN USER MODE, WHICH THEN OUTPUTS
		;STUFF IN ITS OWN FORMAT TO THE DISK
	;COMMUNICATION IS VIA DMNBUF (BUFFER) AND POINTERS,
	;DEMON JOB FINDS IT BY LOOKING UP SYSTEM SYMS

	;USAGE:
	;ROUTINES MUST BE CALLED WITH CLK OFF OR IN PROGRESS
	;FIRST CALL DMNP TO SET UP D AS "PDL POINTER" INTO DMNBF
	;DMNPSH ADR	;PUSH ADR INTO DMNBF (ASSEMBLES INTO A PUSH)
		;FIRST WORD PUSHED SHOULD HAVE ENTRY TYPE DESCRIPTOR IN HIGH SIX BITS

	;ENTRY TYPE DESCRIPTORS:
DMNELI==10000	;LOGIN (DMNPLI)
DMNELO==20000	;LOGOUT (DMNPLO)
	;^ ADD MORE AS NEEDED, NEED NOT BE SYMBOLIC BUT PLEASE COMMENT THEM HERE FOR XREF

	;DMNRS		;NORMALLIZE POINTER (DUE TO STANDARD LENGTH ENTRY IN TABLE)
		;ASSEMBLES INTO ONE STORAGE WORD
	;THEN CALL (PUSHJ) DMNRT WHICH STORES BACK D
	;ALL DMNPSH'S SHOULD BE ASSEMBLED BEFORE DMNRT;
	;ALL ROUTINES SHOULD BE BETWEEN THIS PAGE AND DMNBUF

;DMNSZ (# ENTRIES IN DMNBF) DEFINED EARLY IN SYSTEM ENGLISH SO CAN BE CHANGED EASILY

DMNFMT==2	;ASCENDING FORMAT NUMBER, SHOULD BE INCREMENTED EACH TIME
			;A CHANGE IS MADE REQUIRING CHANGE IN CODING EITHER OF DEMON JOB
			;OR OF PROGRAMS READING ITS OUTPUT
;DMNFNT 1 -> 2 9/71 SWAPIN RQ INCLUDED W/LOGOUT

DMNBAC==0	;DMNPSH COUNTER, AFTER FIRST TIME GETS RE-INITIALIZED TO DMNBLM

DEFINE DMNPSH ADR
	DMNBAC==DMNBAC+1
	PUSH D,ADR
TERMIN

IF1,DMNBEL==0		;BECOMES LENGTH PER ENTRY IN DMNBF

DEFINE DMNRS
	ADDI D,DMNBEL-DMNBAC
IF1,IFG DMNBAC-DMNBEL,DMNBEL==DMNBAC
DMNBAC==DMNBLM
TERMIN

		;PUSHJ P,DMNP	;SET UP D FOR DMNPSH'S INTO DMNBF

DMNP:	MOVE D,DMNBFP	;GET POINTER
	CAIL D,DMNBFE-1	;AT END OF BUFFER?
	MOVEI D,DMNBF-1	;YES, RE-INITIALIZE
	AOS DMNBC	;INDICATE ENTRY ABOUT TO BE FILLED, SO DEMON KNOWS IF IT LOST
DMNP0:	;DMNP0 MAY BE CALLED IN USER MODE FROM DEMON JOB
	DMNPSH TIME	;FIRST WORD IN BUFFER ALWAYS TIME OF ENTRY
		;^ MAYBE ADD MORE STANDARD PUSHES HERE
	POPJ P,

DMNBLM==DMNBAC	;NUMBER OF INITIAL WORDS PUSHED

		;PUSHJ P,DMNRT (BUT USUALLY JRST DMNRT FOR RETURN)
			;DMNBF ENTRY COMPLETED, STORE BACK POINTERS

DMNRT:	TLZ D,-1	;CLEAR OUT LEFT HALF OF POINTER
	CAIL D,DMNBFE	;AFTER END OF BUFFER?
	JRST 4,.+1	;DMNBF POINTER INCREMENTED INCORRECTLY SOMEWHERE ALONG THE LINE
		;PROBABLY PROGRAMMER FORGOT TO DO DMNRS; CODING AFTER DMNBF MIGHT BE CLOBBERED
	AOS DMNBD	;ENTRY COMPLETE, GIVE IT TO DEMON JOB
	MOVEM D,DMNBFP
	POPJ P,

		;NOW FOR INDIVIDUAL ROUTINES

		;LOGIN

DMNPLI:	PUSHJ P,DMNP	;SET UP
	HRLI U,DMNELI	;INDICATE LOGIN
		;PUT FOLLOWING INTO DMNBF:
	DMNPSH U	;INDEX OF USER BEING LOGGED IN
	TLZ U,-1
	DMNPSH UNAME(U)	;UNAME
	DMNPSH JNAME(U)	;JNAME
	DMNPSH TRMNAM(U)	;TERMINAL NAME
	DMNPSH XUNAME(U)
	DMNRS		;THAT'S ALL
	JRST DMNRT

		;LOGOUT

DMNPLO:	PUSHJ P,DMNP		;SET UP D
	PUSHJ P,LOGUSE		;GET TREE'S USAGE IN T AND TT
	HRLI U,DMNELO		;INDICATE LOGOUT
		;PUT FOLLOWING IN DMNBF FOR DEMON JOB TO DUMP OUT ON DISK:
	DMNPSH U		;INDEX OF USER BEING LOGGED OUT
	TLZ U,-1
	DMNPSH UNAME(U)		;UNAME OF USER
	DMNPSH JNAME(U)		;JNAME
	DMNPSH TT		;TIME USED, IN 4.069 USEC UNITS
	DMNPSH T		;# SWAPIN REQUESTS (THESE VALID SINCE LOGUSE ALREADY CALLED)
		;^ ADD MORE HERE
	ADDM TT,LOUTIM		;COUNT UP TOTAL TIME USED BY ALL LOSERS
	DMNRS
	JRST DMNRT

DMNPL0==CPOPJ	;DMNPL0 MAY BE CALLED FROM DEMON JOB IN USER MODE
		;IT IS NO LONGER POSSIBLE TO MAKE THIS WORK RIGHT,
		;SO WE JUST RETURN.  PFTHMG DRAGON SHOULD BE FIXED.

EBLK
		;DEMON VARIABLES, MUST FOLLOW CODING
		;USE CARE IN REDEFINING SYMBOLS ON THIS PAGE; DEMON JOB RUNNING IN USER MODE
			;LOOKS AT SOME OF THEM, EXCEPT AS INDICATED

DMNBF:	BLOCK DMNBEL*DMNSZ	;BUFFER
DMNBFE::

DMNBC:	0	;ENTRY COUNT, INCREMENTED JUST BEFORE ENTRY ADDED TO DMNBF (USED BY DEMON)
DMNBD:	0	;ENTRY COUNT, INCREMENTED JUST AFTER " " "
DMNBFP:	DMNBF-1	;POINTER INTO BUFFER, HAS ADR OF LAST WORD WRITTEN (NOT USED BY DEMON)
VSCLAU:	0	.SEE VSCLA1	;LAST JOB TREE ACCOUNTING UPDATE DONE FOR
		;NO MORE CODING ALLOWED AFTER THIS POINT

DEFINE DMNPSH A
INFORM DMNPSH AT .,\.
TERMIN

DEFINE DMNRS
INFORM DMNRS AT .,\.
TERMIN

BBLK

SUBTTL "SYSTEM" JOBS

IFN TPLP,[
TPLI==11	;PSEUDO LPT IN
PRTO==12	;REAL LPT OUT
]
IFN DEMON,TPLI==11	;FOR DEMON HACKER
IFN DEMON,TEMPC==16	;FOR TESTING WHETHER DEMON FILE EXISTS.
STYOC==17	;OUTPUT "

;CODE FROM ICLR TO SCOR EXECUTED ONLY ONCE (SEE BEG)
ICLR:	MOVE A,[GO,,GO+1]	;PICK UP BLT POINTER (COPY EXCH WORD INTO NEXT)
	SETZM GO	;CLEAR FIRST WORD
	BLT A,IEND	;CLEAR OUT INITIALIZING CODE (IN AREA TO BE USER VAR BLOCKS)
	SKIPL CORRQ	;SKIP IF CORE RQ FOR SYSTEM'S SPACE PROCESSED
	 PUSHJ P,UFLS	;WAIT AS NECESSARY
	PUSHJ P,SYSCOP	;"OPEN" SYSTEM CONSOLE CHANNEL
IFN CCLKP,[
	JRST .+3	;JFCL FOR CHESS CLK MODE
	 PUSHJ P,CLQAD1
	     CCLKB
];CCLKP
IFN IMPP,[
	MOVE A,TIME
	MOVEM A,LNETIM
	PUSHJ P,IMPINI
];IMPP
	MOVEI A,IINTIC
	MOVEM A,IINCNT
SCOR:	MOVE P,SYSPDP
	MOVE U,USER
	CONO PI,CLKON
	MOVE A,TIME
	ADDI A,30.*60.*5	;5 MINUTES BEFORE SHUTDOWN?
	SKIPLE SHUTDN
	 CAMG A,SHUTDN
	  JRST .+3
	   SKIPN SUSRS
	    JRST SYSOUT	;JUMP IF SYS DYING & NO ONE LOGGED IN
	MOVE T,[.HANG]
	MOVEM T,FORTY	;TELL PEEK WHAT OUR UFLS REALLY IS.
	MOVE T,TIME
	MOVEM T,SYSITM
	SKIPN SUPCOR	;SKIP IF ANY BITS ON IN SUPCOR
	 PUSHJ P,UFLS	;HANG TILL A BIT ON
;SYS JOB IS HUNG IF SYSITM IS 30 SEC OLD AND PC ISN'T SCOR1.
SCOR1:	MOVSI A,(SETZ)
	MOVEI B,0
SYSDP1:	TDNE A,SUPCOR
	 JRST SYSDP2
SYSDP3:	LSH A,-1
	JUMPE A,SCOR
	AOJA B,SYSDP1

SYSDP2:	SKIPGE SYSDTB(B)	;SKIP UNLESS 4.9 BIT OF ENTRY ON
	 ANDCAM A,SUPCOR		;4.9 ON, CLEAR SUPCOR BIT
	LDB C,[370200,,SYSDTB(B)]
	TRNE C,2		;IF ROUTINE IS GOING TO USE TTY,
	 PUSHJ P,WARMTTY	;THEN WARM IT UP FOR IT
	TRNE C,1
	 PUSHJ P,DINGTTY
	LDB T,[420100,,SYSDTB(B)]	;GET 4.8 BIT
	JUMPE T,@SYSDTB(B)	;IF 4.8 BIT = 0, JUMP TO ROUTINE
	PUSH P,A	;4.8 .NE. 0, SAVE A
	PUSH P,B	;SAVE B
	PUSHJ P,@SYSDTB(B)	;CALL ROUTINE
	POP P,B		;RESTORE B
	POP P,A		;RESTORE A
	LDB T,[410100,,SYSDTB(B)]	;GET 4.7 BIT
	JUMPE T,SYSDP3	;IF ZERO RETURN TO LOOP
	ANDCAM A,SUPCOR	;NON-ZERO, CLEAR SUPCOR BIT
	JRST SYSDP3	;LOOP

SUBTTL SUPCOR DISPATCH TABLE

;DISPATCH TABLE FOR BITS IN SUPCOR
;4.9 = 1 TO CLEAR SUPCOR BIT BEFORE DISPATCHING
;4.8 = 0, JRST TO ROUTINE ; = 1, PUSHJ
;4.7 = 1 TO CLEAR SUPCOR BIT AFTER (ONLY USEFUL IF PUSHJ)
;4.6 WARM UP TELETYPE BEFORE CALL
;4.5 DING BEFORE CALL

SCL==1,,525252	;BIT TYPEOUT MASK FOR SUPCOR
SCR==525252	; ..

SYSDTB:
SCLEX==400000 ?  300000,,SYSEX	;INCREASE USER-VAR BLOCK SPACE.
SCLSHD==200000 ? 340000,,SYSSHD	;HANDLE .SHUTDN - PRINT "GOING DOWN" MESSAGES.
SCLOUT==100000 ? 400000,,SYSOUT	;TIME FOR SYSTEM TO GO DOWN.
IFE KS10P,[	660000,,SYSCK5	;CHECK FOR DEVICES GIVING SPURIOUS INTERRUPTS.
		SCLCK5==040000]
IFN KS10P,	400000,,SYSDP3
SCLDAT==020000 ? 600000,,DATIME	;CONTINUE TRYING TO DETERMINE DATE AND TIME.
SCLPAR==010000 ? 360000,,PARTYP	;PRINT "PARITY ERROR..."
SCLSET==004000 ? 340000,,SYSSET	;DEPOSIT IN SYSTEM (.SETLOC).
SCLIMP==002000 ? 600000,,SYSIMU	;PRINT "NETWORK UP ..."
SCLWRT==001000 ? 340000,,SYSWRT	;PRINT WRITING-ON-SYS: MESSAGE.
SCLLGI==000400 ? 340000,,SYSLGI	;PRINT LOGIN MESSAGE.
SCLDEC==000200 ? 300000,,SYSDEC	;DECREASE USER-VAR SPACE.
SCLVSK==000100 ? 600000,,VSCLK	;VERY SLOW (2 MINUTE) CLOCK.
SCLGUN==000040 ? 600000,,SYSGUN	;FLUSH TREES THAT ARE TRYING TO LOG OUT.
SCLNET==000020 ? 460000,,SYSNET	;BRING NCP DOWN AND UP.
IFN DEMON,[	600000,,DEMCHK	;RUN ANY DEMONS WHICH NEED IT.
		SCLDMN==000010]
IFE DEMON,	400000,,SYSDP3
SCLNXM==000004 ? 360000,,NXMTYP	;PRINT "NON-EX MEM ERROR ..."
IFE KA10P,[
SCLBPF==000002 ? 360000,,BPFTYP	;BAD PAGE FAIL
].ELSE		 400000,,SYSDP3
SCLIDK==000001 ? 600000,,ISYS	;DISK IS INITIALIZED
SCRTPP==400000 ? 600000,,TPLPRT	;TRANSFER DATA TO LPT (FROM TPL)
SCRTPC==200000 ? 600000,,VSCL6	;SEE IF ANY FILES HAVE BEEN SPOOLED.
		 400000,,SYSDP3
SCRHNG==040000 ? 600000,,SYSDIL	;DIALUP LINE CONNECT OR DISCONNECT
SCRDET==020000 ? 600000,,SYSDT	;DETACH TOP-LEVEL JOBS WITH INTERRUPTS.
SCRCFM==010000 ? 600000,,SYSCFM	;PRINT CONSOLE FREE MSGS
SCRMSG==004000 ? 640000,,SYSMPR	;PRINT RANDOM SYSTEM MESSAG
	REPEAT 5,400000,,SYSDP3	;CAN BE SET BY USER (.SUPSET)
IFN N11TYS,[	600000,,VWHO	;UPDATE WHO LINES (40)
		SCRWHO==000040]
.ELSE		400000,,SYSDP3
IFN N11TYS,[	640000,,SYS11D	;TV 11 GONE DOWN (20)
		SCR11D==000020]
.ELSE		400000,,SYSDP3
IFN N11TYS,[	640000,,SYS11U	;TV 11 COME UP, INIT IT (10)
		SCR11U==000010]
.ELSE		400000,,SYSDP3
IFE DEMON,	400000,,SYSDP3	;(4)
IFN DEMON,[	600000,,DMNOFF
		SCRDMF==000004]
SCRTPF==000002 ? 300000,,TPLOFF	;BLOCK TPL.
SCRCKS==000001 ? 600000,,SYSCKS	;PERFORM CHECKSUMMING

IFN .-SYSDTB-36.,.ERR SYS JOB DISPATCH

SUBTTL DM DAEMON OVERSEER

IFN DEMON,[
DEMCHK:	PUSHJ P,SYSDEX	;HANDLE REQUESTS TO KNOW WHETHER A FILE
			;EXISTS TO BE SIGNALLED AS A DEMON.
	PUSHJ P,LSWTL	;SYSTEM JOB SIEZES DEMON TABLE SWITCH WITH UTCOFF
	 400000,,DEMSW
	MOVE B,DMLSEX
	CAMN B,[-DMLNG,,0]	;IF AT BEGINNING OF TABLE SET FLAG
	 TDZA D,D
	  SETOM D
DMSCN9:	SKIPE TT,DMTTBL(B)
	 SKIPE DMTTBL+1(B)	;ONLY PAY ATTENTION IF NOT DOWN
	  JRST DMSCN1	;AND GUY THERE
	MOVE T,DMTTBL+2(B)
	HRRE C,T
	TLNE T,-1
	 JRST DMSCN3
	JUMPLE C,DMSC10
DMSCN0:	SKIPG DMNFLG
	 JRST DMSC11	;IF FLAG SET CAN'T LOAD EM
	CAME TT,[SIXBIT /UNSPOO/]
	 JRST DMSCN4	;DON'T BOTHER WITH TPL STUFF, IF NOT TPL
	SKIPGE TPLFLG
	 JRST DMSC10	;REMOVE FROM WORLD
	JRST DMSCN4

DMSCN4:	HLRM T,DMTTBL+3(B)	;SET UP IMPLICIT REQUEST
	CONO PI,UTCON	;ATTEMPT LOAD HERE
	MOVE T,DMTTBL(B)
	MOVEM T,DMOBLK+2	;CHECK TO SEE IF FILE EXITS
	.IOPUSH TPLI,
	.OPEN TPLI,DMOBLK	;DON'T WORRY CAN'T PCLSR
	 JRST DMSCN5	;OPEN FAILURE
	.IOPOP TPLI,	;GET BACK STUFF
	HRROI T,DMTTBL(B)
	PUSHJ P,NUJBST	;TRY TO LOAD
	 JRST DMSCN6	;COME BACK LATER, NO ENTRY FOR THIS GUY.
DMSCN8:	ADD B,[DMTLL,,DMTLL]
	SKIPL B
	 MOVSI B,-DMLNG
	MOVEM B,DMLSEX	;FIX UP TABLE
DMSCN7:	MOVSI B,SCLDMN
	IORM B,SUPCOP	;IF MORE REQUESTS, RUN AGAIN IN 1 SECOND.
	SOSLE REQCNT	;NO MORE REQUESTS =>
	 JRST LSWPOP
	SETZM REQCNT
	ANDCAM B,SUPCOP	;DON'T RUN AGAIN.
	ANDCAM B,SUPCOR	;THEN CLEAR OUT SUPCOR BIT
	JRST LSWPOP


DMSCN5:	.IOPOP TPLI,	;FILE DOESN'T EXIST
	CONO PI,UTCOFF
DMSC10:	PUSHJ P,DEMMRV	;REMOVE DEAMON
	JRST DMSCN8	;AND REQUEST

DMSCN3:	JUMPG C,DMSCN0	;LOAD
	JRST DMSCN1

DMSCN2:	CONO PI,UTCON	;CONTINUE AROUND LOOP
	ADD B,[DMTLL,,DMTLL]
DMSCN6:	MOVEM B,DMLSEX
	JRST LSWPOP	;COME BACK LATTER WITHOUT FLUSHING REQ

DMSCN1:	ADD B,[DMTLL,,DMTLL]	;ADD ON VAL
	JUMPL B,DMSCN9	;CONTINUE AROUND LOOP
	MOVSI B,-DMLNG
	MOVEM B,DMLSEX
	JUMPE D,UTOLKJ
DMSC11:	SETZM REQCNT	;IF RAN THROUGH WHOLE TABLE WITHOUT ANY PROCESS
	CONO PI,UTCON
	JRST DMSCN7	;FLUSH ALL REQUESTS AND RETURN

DMNOFF:	MOVNS TT,DMNFLG
	JUMPLE TT,DMNOF1	;DEAMONS OFF
	PUSHJ P,LSWTL
	    DEMSW
DMNOF3:	SKIPE DMTTBL(B)
	 SKIPE DMTTBL+1(B)
	  JRST DMNOF2
	AOS REQCNT
DMNOF2:	ADD B,[DMTLL,,DMTLL]
	JUMPL B,DMNOF3
	MOVSI B,SCLDMN
	IORM B,SUPCOR
	JRST LSWPOP

DMNOF1:	MOVSI B,SCLDMN
	ANDCAM B,SUPCOR
	SETZM REQCNT	;ZERO COUNT
	POPJ P,

;CALL HERE TO HANDLE ALL JOBS THAT ARE WAITING IN .DEMSIG TO
;BE TOLD WHETHER A PURPORTED DEMON REALLY EXISTS. GIVE THEM
;THEIR ANSWERS AND START THEM UP AGAIN.
SYSDEX:	SETZ A,
	MOVEI C,'SYS
	MOVE D,['ATSIGN]
SYSDE1:	CONO PI,CLKOFF
	SKIPN SRN3(A)	;THIS JOB'S ALREADY BEEN SERVICED?^
	 SKIPN UNAME(A)	;OR DOESN'T REALLY EXIST?
	  JRST SYSDE3
	MOVE B,UPC(A)	;IS IT WAITING FOR SERVICE FROM US?
	XORI B,ADEMS1	;MUST BE IN EXEC MODE AT THE RIGHT PLACE.
	TDNE B,[%PCUSR,,-1]
	 JRST SYSDE3
	MOVE E,AC0S+A(A) ;GET THE FN2 IT WANTS TO CHECK.
	CONO PI,CLKON
	SETZ T,		;T GETS 0 IFF FILE CAN BE OPENED.
	.OPEN TEMPC,C
	 CAIA
	  JRST SYSDE2
	LDB T,[220600,,IOCHST+TEMPC]
	SKIPN T
	 MOVEI T,%ENSFL
SYSDE2:	.CLOSE TEMPC,
	CONO PI,CLKOFF
	SKIPN UNAME(A)	;SEE IF JOB IS STILL WAITING FOR SERVICE
	 JRST SYSDE3	;SO IT ISN'T CLOBBERED IF IT GOT AN
	MOVE B,UPC(A)	;INTERRUPT AND IS DOING SOMETHING ELSE.
	XORI B,ADEMS1
	TDNN B,[%PCUSR,,-1]
	 CAME E,AC0S+A(A)
	  JRST SYSDE3
	MOVEM T,AC0S+T(A) ;GIVE THE JOB ITS ANSWER IN T, AND
	SETOM SRN3(A)	;TELL THE JOB IT HAS BEEN SERVED.
SYSDE3:	CONO PI,CLKON
	ADDI A,LUBLK
	CAMGE A,USRHI
	 JRST SYSDE1
	POPJ P,
];DEMON

SUBTTL VERY SLOW CLOCK

;SUBROUTINES CALLED BY THE VERY SLOW CLOCK.

;CHECK FOR DEMON REQUESTS WHOSE TIME HAS COME.
IFN DEMON,[
VSCLDM:	PUSHJ P,LSWTL
	DEMSW
	MOVSI B,-DMLNG
VSCLD2:	SKIPG DMTTBL+3(B)	;IF SPECIFIC ENTRY IS < = O, IGNORE
	JRST VSCLD1
	SOSE DMTTBL+3(B)
	JRST VSCLD1
	HLRZ T,DMTTBL+2(B)	;SIGNAL DEAMON
	MOVEM T,DMTTBL+3(B)
	MOVE A,DMTTBL(B)
	PUSHJ P,DEMSIG	;SIGNAL REQUEST FOR THIS GUY
	 BUG		;ENTRY IN TABLE NOT FOUND EVEN THOUGH NON ZERO TIME
VSCLD1:	ADD B,[DMTLL,,DMTLL]
	JUMPL B,VSCLD2
	JRST LSWPOP
]

;CHECK FOR CLOBBERED TEN-11 INTERFACE CONTROL PAGE WORDS,
;AND RESET THEM TO THEIR CORRECT SETTINGS.
IFN TEN11P,[
T11CK:	SKIPE TEN11F
	POPJ P,
	MOVSI I,-256.
T11CKL:	MOVE A,T11MP(I)
	CAMN A,[-1]
	MOVEI A,0	;HARDWARE SHOULD BE 0 ON CONFLICT PAGE
	TLZ A,174000	;USAGE COUNT
	MOVE B,400000+T11CP*2000(I)
	CAME A,B
	JRST T11ERR
T11CL1:	AOBJN I,T11CKL
	POPJ P,

T11ERR:	AOS T11ERC
	MOVEM A,400000+T11CP*2000(I)
	MOVEM A,T11CCN
	MOVEM B,T11WCN
	MOVEM I,T11PG
	JRST T11CL1
]

;VERY SLOW CLOCK (EVERY 2 MIN). SIGNALLED BY SCLVSK, SET BY A CLOCK-QUEUE ENTRY.
;CALLS THE ULTRA-SLOW CLOCK (EVERY 2 HOURS) WHEN IT'S TIME.

VSCLK:;JSP E,CHECK		;CHECK FOR CLOBBERED DEVICES (WOULD BE NICE, BUT BUGS...)
IFN DEMON,PUSHJ P,VSCLDM	;DEAMON SLOW CLOCK BREAK ROUTINE
IFN TEN11P,PUSHJ P,T11CK
	MOVE U,VSCLAU	;ACCOUNTING UPDATE, FIND A JOB TREE
VSCLA1:	ADDI U,LUBLK
	CAML U,USRHI
	 MOVEI U,0
	SKIPE UNAME(U)
	 SKIPL SUPPRO(U)
	  JRST VSCLA1
	HRLO TT,UNAME(U)
	AOJE TT,VSCLA1	;DON'T IF NOT LOGGED IN YET
	MOVEM U,VSCLAU
	CONO PI,CLKOFF
	PUSHJ P,LOGUPD
	PUSHJ P,DMNPLI
	CONO PI,CLKON
	MOVE U,USER
	SKIPLE CTLCNT	;Time to print date on console log?
	 JRST VSCLA2	; No.
	PUSHJ P,GLPDTM	;Yes - get localized pdtime.
	 JRST VSCLA2	; Can't print time if we don't know it.
	PUSHJ P,WARMTTY	;Warm up tty, newline.
	PUSHJ P,DATIM6	;Print what time it is now.
	MOVEI TT,CTLMAX	;Restart countdown of lines printed.
	MOVEM TT,CTLCNT
VSCLA2:	PUSHJ P,VSCOLD	;CHECK FOR OLD DETACHED TREES TO BE KILLED
	PUSHJ P,TTTMNT	;TURN OFF MOTORS OF IDLE TERMINETS.
VSCL7:	SETOM UFDFLF	;CAUSE CORE JOB TO TRY TO FLUSH 2311 UFDS
	AOS NCORRQ
	MOVSI I,-NCLCH	;LOOK FOR UNOPEND CORE LINK BUFFERS THAT HAVE BEEN
	PUSHJ P,SWTL	;AROUND FOR MORE THAN 2 MINUTES
	    CLOSW
VSCLCL:	SKIPE CLSYN(I)	;SKIP IF VARS UNUSED
	 SKIPL A,CLUSR(I)
	  JRST VSCLC2
	AOJN A,VSCLC2	;JUMP IF OPEN
	MOVE TT,CLRAC(I)
	TLOE TT,200000
	 JRST VSCLCR	;BIT ALREADY ON, BUFFER OLD
	MOVEM TT,CLRAC(I)
VSCLC2:	AOBJN I,VSCLCL	;LOOP FOR ALL SETS OF VARIABLES
	PUSHJ P,LSWPOP	;RELEASE SWITCH

	MOVE A,UTTBF	;IF MANY 200-WORD BUFFERS ARE FREE,
	CAIGE A,8
	 JRST .+3
	  SETOM UTBFLF	;HAVE THE CORE JOB FLUSH THEM
	  AOS NCORRQ

IFN IMPP,[
	SKIPGE IMPUP	;SKIP IF IMP UP, OR PERMANENTLY DOWN
	 PUSHJ P,SYSIMU	;TRY TO BRING IT UP
];IMPP
IFN TPLP,PUSHJ P,VSCL6	;MAYBE START PRINTING FROM .LPTR.
IFN NLPTP,[
	SKIPL NLUSR	;IF LPT ISN'T IN USE,
	 JRST VSCNL1
	AOS TT,NLFREE	;KEEP TRACK OF HOW LONG THAT'S BEEN SO.
	SOJN TT,VSCNL1	;IF TRUE FOR >=2 VSCLK INTREVALS (4 MIN)
	CONO NLPT,1000	;TURN LPT MOTOR OFF: 1ST PUT LPT IN IMAGE MODE
	DATAO NLPT,[.BYTE 7 ? 24 ? 177 ? 177 ? 177 ? 177] ;THEN TURN OFF.
VSCNL1:]
	SOSLE IINCNT
	 POPJ P,

;IT'S TIME FOR THE ULTRA-SLOW CLOCK
	MOVEI A,IINTIC	;GET HERE EVERY TWO HOURS OR SO
	MOVEM A,IINCNT
	PUSHJ P,GLPDTM
	 POPJ P,	;TIME NOT KNOWN
	PUSHJ P,WARMTTY
	JRST DATIM6	;TIME KNOWN, TELL SYSTEM CONSOLE

VSCLCR:	HRRZ A,TT
	PUSHJ P,BRTN	;RETURN BUFFER
	SETZM CLSYN(I)	;FREE VARIABLES
	JRST VSCLC2

;CHECK FOR TREES WITH BUMRTL SET THAT HAVE NOT RUN FOR
;A WHOLE HOUR, AND GUN THEM.
VSCOLD:	SETZB U,J
	CONO PI,CLKOFF
	MOVSI B,BUMRTL
	MOVSI C,BULGOS
	MOVE A,TIME
	SUBI A,60.*60.*30.	;1 HOUR AGO
VSCOL0:	SKIPE UNAME(J)
	 TDNN B,APRC(J)
	  JRST VSCOL1	;JOB NON EX OR DOSN'T HAVE BUMRTL
	SKIPGE SUPPRO(J) ;NO GOOD IF NOT TOP LEVEL.
	 TDNE C,APRC(J)	;IGNORE JOBS THAT ARE ALREADY LOGGING OUT.
	  JRST VSCOL1
	CAML A,LUBTM(J)	;NOT RUNNING AND HASN'T RUN FOR 1 HOUR => GUN.
	 JRST VSCOL2
VSCOL1:	ADDI J,LUBLK	;KEEP LOOKING TILL FIND JOB THAT NEEDS GUNING.
	CAMGE J,USRHI
	 JRST VSCOL0
	JRST CLKONJ	;NO TREES NEED TO BE GUNNED.

VSCOL2:	MOVEI I,[ASCIZ /KILLED HOUR-OLD DETACHED JOB, # /]
	PUSHJ P,SYSJEX	;PRINT MESSAGE AFTER CALLING ALOGO6
	    PUSHJ P,ALOGO6
	JRST VSCOLD	;LOOK FOR ANOTHER TREE TO GUN.

;	MOVEI I,[ASCIZ/DID FOO TO JOB # /]
;	PUSHJ P,SYSJEX
;	    PUSHJ P,FOO
;DOES FOO TO THE JOB WITH IDX IN J, AND PRINTS A SYSTEM MSG.
;FOO WILL FIND THE USR IDX IN A AND J. IT IS OK TO ENTER
;SYSJEX WITH CLOCK OFF BUT FOO MUST TURN IT ON.
SYSJEX:	HRRZS A,J
	PUSH P,JNAME(A)
	PUSH P,UNAME(A)
	PUSH P,A	;SAVE ALL THE INFO WE NEED FOR THE MESSAGE.
	PUSH P,I
	XCT @-4(P)	;DO "FOO"
	 JFCL		;LET FOO SKIP.
	AOS -4(P)	;SKIP OVER THE PUSHJ TO FOO.
	PUSHJ P,WARMTTY
	HRRZ I,(P)
	PUSHJ P,SYSSP	;PRINT THE STRING IN I
	POP P,I
	HLRZS I
	SKIPE I
	 PUSHJ P,(I)	;IF LH(I) WAS NONZERO, CALL THAT PRINT ROUTINE
	POP P,A
	IDIVI A,LUBLK
	PUSHJ P,SYSOPT	;PRINT THE JOB #
	MOVEI I,[ASCIZ /, USR:/]
	PUSHJ P,SYSSP
	POP P,A
	PUSHJ P,SYSIXP	;PRINT UNAME, AND SPACE
	PUSHJ P,STYOS
	POP P,A
	PUSHJ P,SYSIXP	;PRINT JNAME
	JRST SYSTCR	;SPACE, TIME AND CR.

SUBTTL TPL

VSCL6:	;CHECK TPL: SEE IF LPT FREE AND ANY FILE TO PRINT.
IFN UNSPLP,[
	PUSHJ P,LSWTL
	DEMSW
	MOVE A,[SIXBIT /UNSPOO/]
	PUSHJ P,DEMSIG
	JRST LSWPOP	;REQUEST FAILED, TOO BAD
	JRST LSWPOP
]

IFE TPLP,POPJ P,
IFN TPLP,[
	MOVEI A,SCRTPP	;ALSO ENTER HERE FOR TPL CHECK
	TDNE A,SUPCOR	;SKIP IF NOT ALREADY PRINTING FILE
	POPJ P,
  IFG LPTP-1,[
	SKIPE TPLSWP
	JRST VSCL6A
	SKIPLE NLPTBR
	SKIPL LPTUSR
	POPJ P,
VSCL6B:
  ]
  IFLE LPTP-1,[
	SKIPL LPTUSR
	POPJ P,
  ]
  IFG OLPTP-NLPTP,[
	MOVEI A,132.
	CAMLE A,LPTCC
	POPJ P,
  ]
  IFG NLPTP-OLPTP,[
	CONSO NLPT,207
	 SKIPG NLPTBR
	  POPJ P,	;.OPEN OF LPT WOULD HANG
  ]
	MOVEI A,SCRTPF
	TDNE A,SUPCOR	;BLOCKED
	 POPJ P,
	.OPEN TPLI,[SIXBIT /   TPL.FILE.(DIR)/]	;MAKE SURE FILE DIR IN CORE
	 JRST VSCLX1
	MOVEI B,2
VSCL2:	.IOT TPLI,A
	CAIE A,^C
	CAIN A,12
	SOJG B,VSCL2
	JUMPN B,VSCL2
	SETOB I,C
	SETZM TPLFN1
	SETZM TPLFN2
	MOVEI B,TPLFN1
	HRLI B,440600
VSCL2A:	.IOT TPLI,A
	CAIN A,"*
	 JUMPL I,VSCL4
	CAIE A,^C
	 CAIN A,14
	  JRST VSCLX1
	CAIN A,40
	 JUMPL I,VSCL2A	;IGNORE SPACES BEFORE THE PACK NUMBER.
	CAIN I,3	;AFTER 4 CHARS STARTING WITH BEGINNING OF PACK NUMBER
	 JRST VSCL2E	;COMES THE START OF THE FN1.
	CAIN A,"L
	 MOVEI C,0	;INDICATE LINK
	AOJA I,VSCL2A	;FIRST NON SPACE CRUFTY

IFG LPTP-1,[
VSCL6A:	MOVEI A,132.
	CAMG A,LPTCC
	SKIPL OLPUSR
	POPJ P,
	JRST VSCL6B
]

VSCL2E:	MOVEI TT,6
VSCL2B:	SUBI A,40
	IDPB A,B
	.IOT TPLI,A
	SOJG TT,VSCL2B
	MOVE B,[440600,,TPLFN2]
VSCL2C:	.IOT TPLI,A
	SUBI A,40
	IDPB A,B
	TLNE B,770000
	JRST VSCL2C
	.IOPUSH TPLI,
	.OPEN TPLI,TPLFN
	JRST VSCLL1	;TRY AGAIN
	.IOPOP PRTO,
	.CLOSE PRTO,
IFN NLPTP,[
IFN OLPTP,[
	SKIPE TPLSWP
	JRST VSCL3A
]
	CONSZ NLPT,207
	 JRST VSCLX1
	MOVEI T,LPTBSZ
	CAMN T,NLPTBR	;SKIP ON OPEN WOULD HANG
 	.OPEN PRTO,[3,,(SIXBIT /LPT/)]
	JRST VSCLX1
IFN OLPTP,[
	JRST VSCL3B
VSCL3A:
]]
IFN OLPTP,[
	MOVEI A,132.
	CAMG A,LPTCC	;SKIP IF .OPEN WOULD HANG
IFN NLPTP,.OPEN PRTO,[3,,'OLP]
.ELSE	.OPEN PRTO,[3,,(SIXBIT /LPT/)]
	JRST VSCLX1
VSCL3B:
]
	MOVEI A,SCRTPP
	IORM A,SUPCOR	;PRINT THIS FILE
	IORM A,SUPCOP	;PRINT MORE EVERY SECOND.
	JRST TPLPRT

VSCLL1:	.IOPOP TPLI,
	JUMPL C,VSCLX1
	MOVEI B,1	;LINK THAT DIDN'T EXIST
	JRST VSCL2
]

IFN TPLP,[
;COME HERE TO TRANSFER SOME CHARS FROM DSK TO LPT,
;ASSUMING BOTH CHNLS ALREADY OPEN.
TPLPRT:
IFN NLPTP,[
IFN OLPTP,[
	SKIPE TPLSWP
	 JRST TPLPR3
]
	MOVEI A,TPLBSZ
	CAMLE A,NLPTBR
	 POPJ P,
IFN OLPTP,[
	JRST TPLPR5
TPLPR3:
]]
IFN OLPTP,[
	MOVEI A,10.*TPLBSZ	;LEAVE SPACE FOR CHARS THAT TAKE MORE THAN 1 CHAR
	CAMLE A,LPTCC
	 POPJ P,
TPLPR5:
]
	MOVE A,[-TPLBSZ,,TPLBUF]	;"UN-RELOCATE"
	.IOT TPLI,A
	MOVE B,A
	MOVNI A,-TPLBUF(A)
	HRLZS A
	JUMPE A,TPLPR1	;JUMP ON END OF FILE
	HRRI A,TPLBUF
	.IOT PRTO,A
	JUMPL B,TPLPR1	;LAST BUFFER-FULL PRINTED
	JRST TPLPRT

TPLPR4:	CLEARM TPLFN3
	.FDELE TPLFN	;DELETE FILE JUST PRINTED
	 JFCL
	MOVEI A,SCRTPP
	ANDCAM A,SUPCOP	;DON'T NEED TO CALL TPLPRT EVERY SECOND.
	ANDCAM A,SUPCOR
VSCLX1:	.CLOSE PRTO,
	.CLOSE TPLI,
	POPJ P,

VSCL4:	.IOT TPLI,A
	CAIN A,14
	 JRST VSCLX1
	CAIN A,12
	 JRST VSCL2A
	JRST VSCL4

TPLPR1:	PUSHJ P,TPLPR4
	JRST VSCL6
]
.ELSE TPLPRT==CPOPJ

;HANDLE A USER'S REQUEST TO "BLOCK THE TPL"
IFN TPLP,[
;IF SYS JOB IS SPOOLING, JUST THROW AWAY CURRENT FILE.
TPLOFF:	MOVEI A,SCRTPP
	TDZN A,SUPCOP
	 POPJ P,		;NOTHING HAPPENING
	PUSHJ P,WARMTTY
	.RESET PRTO,
	PUSHJ P,TPLPR4
	MOVE A,[SIXBIT /TPLOFF/]
	PUSHJ P,SYSIXP
	JRST SYSTCR
]

IFE TPLP+UNSPLP,TPLOFF==CPOPJ

IFN UNSPLP,[
TPLOFF:	MOVNS B,TPLFLG
	JUMPG B,VSCL6	;IF NOW RUNNING GIVE REQ
	MOVSI B,-DMLNG
TPLOF1:	SKIPE C,DMTTBL(B)
	SKIPG D,DMTTBL+1(B)	;USER INDEX -0 IF NOT YET LOADED
	JRST TPLOF2
	CAME C,[SIXBIT /UNSPOO/]
	JRST TPLOF2
	PUSH P,U
	MOVE U,D
	PUSHJ P,ALOGOUT	;DOES ONE USTOP FOR YOU
	POP P,U
	JRST TPLOF3

TPLOF2:	ADD B,[DMTLL,,DMTLL]
	JUMPL B,TPLOF1
TPLOF3:	PUSHJ P,WARMTTY
	MOVE A,[SIXBIT /TPLOFF/ ]
	PUSHJ P,SYSIXP
	JRST SYSTCR
]

SUBTTL WHO LINES

IFN N11TYS,[
;PDP11 COMM AREA (SYSTEM WIDE)
;STARTS AT PDP11 ADDRESS 40
;PNTR TO TT11HD
;PNTR TO POINTA
;I/O VERSION #
;SORCE FILE VERSION #
;--PDP10 WD BOARDARY--  0 , INITED
;                       0 , GODOWN

;AT POINTA:
;	ADDR OF SYSTEM WHO-LINE VARS
;	ADDR OF 10-11 COMMAND BUFFER
;	TENWHO , 0	;PDP10 SETS TO TELL PDP11 TO UPDATE WHO-LINES
;	MAXTV , 0	;MAXTV = # TV'S 11 IS SET UP TO HANDLE
;	NF11TY , 0	;10 TELLS 11 WHAT TTY # OF 1ST BUFFER IS.

;PDP11 CONSOLE VARS
;	  EVEN PDP11 WORD                 ODD PDP11 WORD
;TT11HD - CHAIN OF ACTIVE INPUT BUFFERS   0
;         PNTR TO OUTPUT BUFFER CHNL 0    VIDEO BUFFER,KBD # (377 IF NONE)
;          "                    CHNL 1     "
;...
;         OUTPUT BFR EMPTY NOTIFY RQ       FLAG TO FREE CHNL
;...
;	  PNTR TO WHO LINE BLOCK           FREE

;THE 11 HAS COME UP, SO INIT COMMUNICATION VARIABLES AND START USING IT
SYS11U:	SKIPG TT11P
	 POPJ P,
	LDB A,[$11AD0,,TT11HA]		;GET PDP10 ADDRESS OF INPUT-BFR-CHAIN PTR
	CAIL A,NTTPG*2000
	 BUG HALT,[GARBAGE POINTER IN TV-11 MEMORY]
	ADDI A,TT11LO
	CONO PI,TTYOFF
	MOVEM A,TT11HD			;SAVE IT FOR CLOCK LVL TO CHECK.
	LDB C,[$11WD0,,TT11HA+1]	;GET PDP11 IO VERSION #.
	MOVEI B,12.			;OLD TV PROGRAMS HANDLE 12. BUFFERS
	LDB T,[$11AD1,,TT11HA]		;GET ADDR OF POINTA
	CAIL C,3			;VERSION 3 AND UP TV PGM HAS MAXTV - READ IT
	 LDB B,[$11WD0,,TT11LO+2(T)]
	MOVEM B,TT1111			;THAT'S HOW MANY TV'S THE 11 THINKS TERE ARE
	CAIL B,N11TYS
	 MOVEI B,N11TYS			;MIN OF THAT AND # TEN THINKS THERE ARE
	MOVEM B,TT11RL
	MOVEI B,NF11TY
	CAIL C,3			;VERSION 3 TV PGM AND UP WANTS NF11TY
	 DPB B,[$11WD0,,TT11LO+3(T)]
	HRLZ I,TT11RL			;GET AOBJN -> TV'S BOTH 10 AND 11 WILL HANDLE.
	MOVNS I
VSCL7C:	LDB B,[$11AD0,,1(A)]		;GET DPY BUFFER ADRESS FOR THIS TTY
	ADDI B,TT11LO+2			;CONVERT TO PDP10 ADDRESS.
	HRLI B,040000+TT11BY_6		;GET BP TO ILDB 1ST DATA WORD.
	MOVEM B,NF11TY+TOBBP(I)		;PNTR TO BEG OF OUTPUT BUFFER
	LDB C,[$11AD0,,(B)]		;GET # BYTES IN DATA AREA
	ADDI B,(C)			;GET BP TO LAST WORD IN AREA
	MOVEM B,NF11TY+TOBEP(I)
	MOVEM B,NF11TY+TOIP(I)
	ADDI A,1
	AOBJN I,VSCL7C
	MOVEM C,TT11OL			;REMEMBER LENGTH OF OUTPUT BUFFERS.
	SETOM TT11P			;TV TTYS NOW UP.
	CONO PI,TTYON
	MOVE A,[-N11TYS,,NF11TY]
	MOVSI B,%TACFM			;NOW SAY ALL PDP11 TTYS NEED
	ANDCAM B,TTYSTA(A)		;CONSOLE FREE MESSAGES,
	AOBJN A,.-1
	MOVEI A,SCRCFM
	IORM A,SUPCOR			;TELL SYS JOB TO PRINT THEM.
	PUSHJ P,CLQAD1			;ADD WHO LINE BLOCK TO CLOCK QUEUE IF NOT THERE
	 WHOCLB
	MOVEI I,[ASCIZ /TV 11 IS UP -/]
	JRST SYSSTD			;STRING,SPACE TIME AND DATE THEN CR
]

IFN N11TYS,[

$INSRT WHOVAR

;UPDATE WHO-LINE VARIABLES.
VWHO:	SKIPL TT11P		;DON'T SCREW UP IF PDP11 ISN'T UP.
	 POPJ P,
	MOVE A,TT11HD
	HRLZ A,TT11RL
	MOVNS A
	HRR A,TT11HD		;-<# TV'S BEING USED>,,<HEADER ADDR>
	ADD A,TT1111
	ADD A,TT1111		;NOW RH -> 2 11-WDS BEFORE PTR TO WHOLINE VARS OF 1ST TV
VWHO1:	LDB B,[$11AD0,,1(A)]	;GET WHO LINE VAR PDP11-ADDR, SHIFTED 2.
	ADDI B,TT11LO		;CONVERT TO PDP10 ADDRESS.
	CONO PI,TTYOFF
	MOVE TT,WHJOB(B)	;JOB # (SHIFTED 4+16.)
	MOVE C,WHMODE(B)	;MODE (SHIFTED 4+16.)
	JUMPG C,VWHO3
	CONO PI,TTYON
	JUMPL C,VWHO2		;MODE < 0 => NO WHOLINE.
	HLRE I,A		;GET -<# TIMES REMAINING THRU LOOP>
	ADD I,TT11RL
	HRRZ TT,TTYSTS+NF11TY(I) ;MODE 0, USE JOB WHICH HAS THE TTY.
	MOVE Q,TT
	IDIVI Q,LUBLK
	LSH Q,4.+16.
	MOVEM Q,WHJOB(B)
;FOR OTHER MODES, COME BACK HERE, WITH USER IDX IN TT.
VWHO3R:	CONO PI,CLKOFF
	MOVE C,UNAME(TT)
	HLLZM C,WHUNAM(B)
	HRLZM C,WHUNM2(B)	;STORE THE JOB'S UNAME
	MOVE C,JNAME(TT)
	HLLZM C,WHJNAM(B)
	HRLZM C,WHJNM2(B)	;AND JNAME.
	MOVE C,USYSNM(TT)
	HLLZM C,WHSNAM(B)
	HRLZM C,WHSNM2(B)	;AND SNAME.
	MOVE C,[SIXBIT /STOP/]
	SKIPE USTP(TT)		;AND "STATUS": IF NOT RUNNABLE, "STOP".
	 JRST VWHO4
	MOVE C,[SIXBIT /RUN/]	;IF NOT WAITING, "RUN".
	SKIPN FLSINS(TT)
	 JRST VWHO4A
	MOVE C,[SIXBIT /PAGE/]	;DETECT WAITING FOR PAGE.
	MOVE Q,USWST(TT)
	TLNE Q,200000
	 JRST VWHO4
	JRST VWHO4B

VWHO4A:	MOVE E,UPC(TT)		;JOB RUNNING: USER MODE?
	TLNE E,%PCUSR		;IF SO, STATUS IS "RUN" (C ALREADY SET UP)
	 JRST VWHO4
VWHO4B:	MOVE E,SV40(TT)		;ELSE DECODE SYSTEM CALL TO GET STATUS.
	HLRZ Q,E
	CAIN Q,(.CALL)
	 JRST VWHO4D		;SYMBOLIC SYSTEM CALL.
	TRZ Q,17_5
	MOVE I,OPTION(TT)
	TLNN I,%OPDEC
	 JRST VWHO4E
	CAIE Q,40_9
	 CAIN Q,41_9
	  JRST VWHO4F
	CAIN Q,47_9
	 JRST VWHO4F
VWHO4E:	CAIN Q,(.IOT)		;.IOT => DECODE DEVICE IN USE.
	 JRST VWHOI1
	CAIN Q,(.OPER)
	 JRST VWHOO1		;.OPER => DECODE ADDRESS FIELD.
	CAIN Q,(.CALL)
	 JRST VWHOC1		;.CALL BUT NOT SYMBOLIC => DECODE AC FIELD.
	LSH Q,-9
	CAIL Q,40
	CAIL Q,40+NUUOSX
VWHO4F:	 SKIPA C,[SIXBIT /UUO/]	;UNRECOGNIZED UUO.
	  MOVE C,UUOSXB-40(Q)	;ELSE GET SIXBIT NAME OF UUO.
	JRST VWHO4C

;A SYMBOLIC SYSTEM CALL IS IN PROGRESS.
VWHO4D:	MOVE C,LSCALL(TT)	;USE SYSTEM CALL NAME AS STATUS
	CAME C,[SIXBIT /SIOT/]
	 CAMN C,[SIXBIT /IOT/]
	  JRST VWHOI2		;BUT IF IT'S "IOT", DECODE DEVICE TYPE.
VWHO4C:	SKIPE FLSINS(TT)
	 JRST VWHO4
	LSH C,-6
	TLO C,'+_12.		;STICK "+" ON FRONT IF RUNNING IN SYSTEM
;DROPS THROUGH			;(NOT IF IN USER MODE, OR IF HUNG).
;DROPS IN
;COME HERE WITH STATUS AS SIXBIT IN C.
VWHO4:
IFE SWPWSP,	SKIPL USWSCD(TT) ;SKIP IF SWAP-BLOCKED
IFN SWPWSP,[	MOVE Q,USWST(TT)
		TLNN Q,%SWSB
]
		 JRST .+3
		  LSH C,-6
		  TLO C,(SIXBIT/>/)
	HLLZM C,WHSTAT(B)
	HRLZM C,WHSTA2(B)
	MOVEI C,WHJ%RT(B)
	HRLI C,442000
	MOVE Q,JTMU(TT)		;COMPUTE % RUN TIME FROM SCHEDULER PRIORITY.
	MULI Q,100.
	DIV Q,[2.^6]
	IDPB Q,C
	MOVE Q,UTRNTM(TT)
	IDIVI Q,25000.
	IDPB Q,C		;JOB RUNTIME IN .1 SEC UNITS.
	MOVE Q,NMPGS(TT)
	MOVE I,NSWPGS(TT)
	SUBM Q,I
	IDPB I,C		;JOB # REAL PAGES.
	IDPB Q,C		;JOB # VIRTUAL PAGES.
;HANDLE THE USER-SPECIFIED FIELDS IN THE WHOLINE.
	MOVE Q,UWHO1(TT)
	ANDCMI Q,17
	MOVEM Q,1(C)		;STORE JOB'S WHOLINE FLAGS.
	MOVE Q,UWHO2(TT)
	HLLZM Q,2(C)		;STORE FIRST USER WHO VAR
	HRLZM Q,3(C)
	MOVE Q,UWHO3(TT)
	HLLZM Q,4(C)		;STORE SECOND USER WHO VAR
	HRLZM Q,5(C)
VWHO2:	CONO PI,CLKON
	AOBJN A,VWHO1
	JRST VWSYS

VWHOO1:	HRRZ Q,E		;JOB EXECUTING .OPER.
	CAIL Q,MXOPR
	 SKIPA C,[SIXBIT/UUO/]
	  MOVE C,OPRSXB(Q)	;GET .OPER NAME AS STATUS
	JRST VWHO4C

VWHOI2:	SKIPL Q,UUAC(TT)	;NEW SYS CALL IOT
	 JRST VWHO4C		;GETTING ARGUMENTS, UUAC NOT SET UP YET
	MOVE I,C		;SAVE NAME IN I
	JRST VWHOI4

VWHOI1:	LDB Q,[270400,,E]	;.IOT
	SETZ I,
VWHOI4:	ADDI Q,IOCHNM(TT)	;Q HAS IOCHNM WORD ADDR FOR CHANNEL.
	MOVE Q,(Q)		;GET IOCHNM WORD CONTENTS (RH INDEXES TABLES)
	HLRZ C,Q
	HLL Q,IOTTB(Q)		;LH GETS BITS SAYING DIRECTION, BLOCK VS UNIT.
	HLL C,CLSTB(Q)
	TLNE C,%CLSJ		;IF JOB DEVICE
	 JRST [	MOVE C,JBDEV(C)	;GET NAME OF SIMULATED DEVICE
		JRST VWHOI6 ]
	HLLZ C,DCHSTB(Q)	;C GETS DEVICE NAME (LEFT-JUST SIXBIT)
	JUMPL C,VWHOI6		;JUMP IF NORMAL 3-CHARACTER NAME
	MOVSS C			;NO, IS ADDRESS OF 6-CHARACTER NAME
	MOVE C,(C)
VWHOI6:	SETZ D,			;EVENTUALLY MAKE STATUS BE 9 CHARS, NOT 6?
	MOVE E,[360600,,C]
	ILDB J,E		;FIND FIRST SPACE IN THAT DEVICE NAME
	JUMPN J,.-1
	JUMPGE Q,VWHOI3  .SEE %IOTBK	;IF BLOCK MODE, PUT A "B" THERE.
	MOVEI J,'B
	DPB J,E
	IBP E
VWHOI3:	CAME I,[SIXBIT /SIOT/]
	 JRST VWHOI5
	MOVEI J,'S
	DPB J,E
	IBP E
VWHOI5:	MOVEI J,'O		;FOLLOW WITH "O" OR "I" SAYING DIRECTION.
	TLNN Q,%IOTOT
	 MOVEI J,'I
	DPB J,E
	JRST VWHO4C		;COMPLETED STATUS LOOKS LIKE "TTYBO".

VWHOC1:	LDB Q,[270400,,E]	;.CALL: GET AC FIELD,
	MOVE C,CALSXB(Q)	;GIVE SIXBIT NAME OF .CALL.
	JRST VWHO4C

;MODE ISN'T 0: FIGURE OUT WHICH JOB TO DISPLAY WHO-LINE FOR,
;AND GO TO VWHO3R WITH JOB'S IDX IN TT. COME HERE WITH TTYCHN OFF.
VWHO3:	LSH TT,-16.-4		;WHAT JOB WAS LAST DISPLAY DONE FOR?
	IMULI TT,LUBLK
	CAMGE TT,USRHI
	 SKIPN D,UNAME(TT)
	  JRST VWHO3B		;JOB WE WERE LOOKING AT HAS VANISHED.
	TLNE C,<-4>_<16.+4-18.>
	 JRST VWHO3B		;THIS TTY IS GETTING SYSTEM WHO-LINE.
	TLNN C,2_<16.+4-18.>
	 JRST VWHO3E		;WANT SAME JOB AS LAST TIME.

;MODE 2 OR 3: COME HERE TO SEARCH FOR DESIRED JOB.
VWHO3A:	MOVSI E,1_<16.+4-18.>
	MOVEM E,WHMODE(B)	;SWITCH TO MODE 1.
	MOVEI E,MAXJ+5		;DON'T LOOP FOREVER
VWHO3D:	ADDI TT,LUBLK		;ADVANCE TO NEXT JOB UP OR DOWN.
	TLNE C,1_<16.+4-18.>
	 SUBI TT,2*LUBLK
	SKIPGE TT		;WRAP AROUND IF NEC GOING DOWN.
	 ADD TT,USRHI
	CAML TT,USRHI		;WRAP AROUND IF NEC. GOING UP.
	 MOVEI TT,0
	CAMN D,UNAME(TT)	;BELONGS TO SOMEONE ELSE => KEEP GOING.
	 JRST VWHO3C		;BELONGS TO THIS USER => STOP.
	SOJG E,VWHO3D		;KEEP LOOKING BUT DON'T LOOP IF NO JOB TO BE FOUND.
VWHO3B:	SETZM WHSTAT(B)		;NO JOB TO BE FOUND.
	CONO PI,TTYON
	JRST VWHO2

VWHO3C:	MOVE Q,TT		;DESIRED JOB FOUND: SET UP FOR MODE 1
	IDIVI Q,LUBLK		;LOOKING AT THIS JOB.
	LSH Q,16.+4
	MOVEM Q,WHJOB(B)
VWHO3E:	CONO PI,TTYON
	JRST VWHO3R


;USER WHO LIES UPDATED; NOW UPDATE SYSTEM WHO LINE VARS.
VWSYS:	LDB A,[$11AD1,,TT11HA]
	LDB B,[$11AD0,,TT11LO(A)]
	ADD B,[$11WD1,,TT11LO]		;FIRST WORD OF BLOCK SET BY 11
	MOVEI C,SRI
	IDPB C,B	;ITS VERSION#.
	MOVEI C,2
	MOVEI E,0
IFN SWPWSP, MOVSI TT,%SWSB
	MOVEI Q,2*LUBLK
VWSYS2:	CAML Q,USRHI	;COUNT # JOBS.
	 JRST VWSYS1
	SKIPN UNAME(Q)
	 JRST VWSYS3
	AOS C		;C GETS # JOBS,
	SKIPE USTP(Q)
	 JRST VWSYS3
IFE SWPWSP,	SKIPGE USWSCD(Q)
IFN SWPWSP,	TDNE TT,USWST(Q)
	 AOS E		;E GETS NUMBER OF ACTIVE SWAPPED BLOCKED JOBS
VWSYS3:	ADDI Q,LUBLK
	JRST VWSYS2

VWSYS1:	IDPB C,B	;TOTAL # JOBS
	MOVE D,MMPCNT
	IDPB D,B	;TOTAL MEM (= TOTAL # PAGES, COUNTING SHARED PAGES ONLY ONCE).
	MOVE C,RNABLU
	SUBI C,1
	IDPB C,B	;RUNNABLE USERS
	IDPB E,B	;# SWAP-BLOCKED JOBS
	MOVE TT,NPGWTU
	IDPB TT,B	;# WAITING FOR PAGE.
	MOVE C,TRUMM	;TOTAL RUNNABLE USER MEMORY
	IDPB C,B
	MOVEI C,0
	MOVE TT,USRHI	;COUNT PAGES AVAILABLE FOR USE OR ACTUALLY USED FOR USER MEM
	ADDI TT,USRSTG+1777
	LSH TT,-10.
VWSYS5:	LDB D,[MUR,,MEMBLT(TT)]
	CAIE D,MURUSR
	CAIN D,MUFR
	 AOS C		;FREE OR USER MEM.
	CAIGE TT,TSYSM-1
	AOJA TT,VWSYS5
	IDPB C,B	;TOTAL MEM AVAIL FOR USERS
	HLRZ C,QDATE
	IDPB C,B
	MOVE C,SYSDBG
	IDPB C,B
	AOS B		;SKIP A WHOLE WORD FOR TIME OF DAY
	MOVEI D,(B)	;SAVE ADDRESS FOR BELOW
	MOVE C,SUSRS	;# LOGGED IN USERS.
	IDPB C,B
	MOVEI E,10000.	;FAIR SHARE IN %
	IDIV E,SLOADU	;BASHES TT
	IDPB E,B
	MOVE C,TIMOFF	;TIME OF DAY IN .5 SEC UNITS.
	LSH C,4
	MOVEM C,(D)	;DEPOSITING TIME OF DAY TRIGGERS WHO-LINE UPDATE
	POPJ P,		; BY THE PDP-11, SO DEPOSIT IT LAST

]	;END IFN N11TYS

SUBTTL EXPAND/CONTRACT USER VARIABLES AREA

SYSEX:	PUSHJ P,SCOREX
	 POPJ P,
	MOVE A,TIME
	MOVEM A,SCITM
	POPJ P,

SYSDEC:	MOVE A,TIME	;TRY TO DECREASE CORE RESERVED FOR USER VARIABLES
	SUB A,SCITM
	CAIG A,50.
	 POPJ P,	;TOO SOON SINCE GOT MORE CORE
	CONO PI,CLKOFF
	MOVE A,USRHI
	SUBI A,LUBLK
	SKIPN UNAME(A)
	 JRST .-2
	ADDI A,LUBLK
	MOVEM A,USRHI	;USRHI=> HIGHEST USER+L
	ADDI A,USRSTG
	ADDI A,1777
	SETOM SJCFF	;INHIBIT ALLOCATION WHILE HUSRAD IS CHANGING
	CONO PI,CLKON
	MOVEI U,0	;FOR ACORE
	LSHC A,-10.-36.	;MOVE INTO B AS WELL
	PUSHJ P,ACORE
	 BUG		;LOST FLUSHING CORE?
	CLEARM SJCFF
	POPJ P,

SCOREX:	LDB B,[121000,,HUSRAD]	;EXTEND CORE FOR USER VARIABLES AT TOP OF SYSTEM
	ADDI B,1
	CAILE B,LIOBLK
	 MOVEI B,LIOBLK		;TRYING TO GET TOO BIG, DON'T
	MOVEI U,0
	JRST ACORE

SUBTTL LOGGER OUT

;THIS ROUTINE AWAKENED BY .LOGOUT, .GUN, ETC.
;SEARCH FOR TREES THAT ARE LOGGING OUT AND READY TO BE FLUSHED
;(IE HAVE BULGO SET) AND FLUSH THEM, PRINTING LOGOUT MESSAGE IF APPRO.
SYSGUN:	SETZ U,
SYSGU0:	MOVE T,APRC(U)
	TLNE T,BULGO	;IS THIS JOB READY TO BE FLUSHED?
	 SKIPN UNAME(U)
	  JRST SYSGU1
IFN NUNITS,[
	SKIPGE TTYTBL(U) ;IF CONSOLE-CONTROLLED, FLUSH UTAPE ASSIGNMENTS
	 JRST SYSGU2
	MOVSI I,-NUNITS
	MOVE A,UNAME(U)
	CAMN A,UTASS+1(I)
	 SETZM UTASS+1(I)
	AOBJN I,.-2
SYSGU2: ]
	HLRO B,UNAME(U)
	AOJE B,SYSGU3	;IF THIS TREE COUNTS AS A LOGGED-IN USER,
	SKIPL TTYTBL(U)
	 SOS SUSRS	;DECREMENT COUNT OF SUCH.
SYSGU3:	CONO PI,CLKOFF
	PUSHJ P,DMNPLO	;UPDATE TREE'S USAGE AND INFORM DEMON JOB
	MOVEM TT,TRUNTM(U)	;SAVE RUN TIME FOR LOGOUT MSG
	CONO PI,CLKON
	SKIPGE A,TTYTBL(U)
	 JRST SYSGU4	;IF TREE HAS CONSOLE,
	SKIPE TTNTO(A)
	 BUG
	PUSHJ P,TTYLO1	;FREE IT.
	CAMN U,EPDL(U)	;UNLESS GUNNED DOWN,
	 SKIPN SUPPLG	;MAY NOT WANT TO BOTHER PRINTING MESSAGE ON SYS CONSOLE
	  SKIPGE DEDTIM
	   JRST SYSGU4	;IF LOGGED OUT BECAUSE SYS DOWN, SPARE THE LOGOUT MSG
	PUSHJ P,WARMTTY
	MOVEI I,[ASCIZ / LOGOUT /]
	PUSHJ P,SYSSP
	MOVE A,UNAME(U)
	PUSHJ P,SYSIXP	;UNAME.
	PUSHJ P,STYOS	;SPACE.
	HRRZ A,TTYTBL(U)
	PUSHJ P,SYSOPT	;TTY #.
	PUSHJ P,SYSTCR
	;VALUE PRINTED IS WRONG, AND HARD TO FIX, SO FOLLOWING CODE HAS BEEN FLUSHED.
	;THE REASON IT'S WRONG IS BECAUSE TIME ALREADY SENT TO THE DAEMON IS NOT INCLUDED.
	;MOVEI I,[ASCIZ / TUSED= /]
	;PUSHJ P,SYSSP
	;MOVE A,TRUNTM(U)
	;MULI A,4069.
	;DIVI A,1000.
	;PUSHJ P,SYSDPC
	;MOVEI I,[ASCIZ / USECS/]
	;PUSHJ P,SYSSTD
	CAMN U,EPDL(U)	;WAS LOGGED OUT BY SELF?
	 JRST SYSGU4
	MOVEI I,[ASCIZ /   ^^  GUNNED DOWN BY /]
	PUSHJ P,SYSSP
	MOVE A,SRN4(U)
	PUSHJ P,SYSIXP	;UNAME OF GUNNER.
	MOVE A,SRN5(U)
	PUSHJ P,SYSSIX	;SPACE, AND JNAME OF GUNNER.
	PUSHJ P,SYSTCR	;CRLF.
;MESSAGES PRINTED IF NECESSARY.
SYSGU4:	SETZ R,
	PUSHJ P,ZUSER	;COMPLETELY ELIMINATE THE JOB.
	CONO PI,CLKON
SYSGU1:	ADDI U,LUBLK
	CAMGE U,USRHI
	 JRST SYSGU0
	SETZ U,
	POPJ P,

;DETACH ANY TREES WHOSE TOP-LEVEL JOBS HAD FATAL INTS

SYSDT:	SETZB U,J
	PUSHJ P,SWTL
	    TREESW
	CONO PI,CLKOFF
	MOVSI B,BUSRC
	MOVSI T,BULGOS+400000
SYSDT0:	SKIPN UNAME(J)
	 JRST SYSDT1
	SKIPGE SUPPRO(J)	;LOOK FOR TOP-LEVEL
	 TDNE T,APRC(J)		;IGNORE JOBS ALREADY DISOWNED, OR LOGGING OUT.
	  JRST SYSDT1
	TDNE B,USTP(J)	;THAT HAS BEEN STOPPED AS BY SUPERIOR
	 JRST SYSDT2
SYSDT1:	ADDI J,LUBLK
	CAMGE J,USRHI
	 JRST SYSDT0
	JRST CLKOPJ	;NO MORE SUCH JOBS, DONE; LSWPOP AND CLKON.

;FOUND A TOP LEVEL JOB NEEDING TO BE DETACHED.
SYSDT2:	PUSH P,J
	MOVE T,OPTION(J)
	TLNE T,%OPLKF
	 JRST [	IDIVI J,LUBLK	;BASHES R
		.CALL [SETZ ? 'UNLOCK ? SETZI %JSNUM(J)]	;UNLOCK THE LOCKS
		 BUG
		MOVE J,(P)
		JRST .+1 ]
	CONO PI,CLKOFF		;IODCSS MIGHT HAVE TURNED IT ON
	SKIPL E,JBI(J)		;NOTE CLKOFF IN EFFECT WHILE HACKING JOB DEVICE STUFF
	 SKIPGE JBCG(E)
	  JRST SYSDTA
	MOVE A,JBCUI(E)		;JOB DEVICE, GIVE IOCER1 OR OPNL7
	LDB T,[000400,,JBSTS(E)]
	CAIE T,1
	 JRST [	MOVSI T,7_5	;NON IOT, UNHANG CREATOR SO WILL SEE OPNL7
		MOVEM T,JBSTS(E)
		MOVE T,FLSINS(A)
		CAMN T,JBFLS
		 SETZM FLSINS(A)
		JRST SYSDTA ]
	MOVEI B,1		;IOT GIVE IOCER1
	MOVS H,E
	PUSHJ P,NSTIOC
	 JFCL
SYSDTA:	POP P,J
	SETZ U,
	MOVE I,[SYSDT8,,[ASCIZ/TOP LEVEL INTERRUPT /]]
	PUSHJ P,SYSJEX
	     PUSHJ P,SYSDT7
	JRST SYSDT

SYSDT8:	MOVE A,-1(P)	;USER INDEX
	MOVE A,PIRQC(A)	;TOP LEVEL INTERRUPT BITS
	PUSHJ P,SYSFWP
SYSDT9:	MOVEI I,[ASCIZ/ DETACHED JOB # /]
	JRST SYSSP

;JOB IN J SHOULD BE DETACHED, AND GUNNED AFTER AN HOUR,
; OR RIGHT AWAY IF NOT LOGGED IN
SYSDT4:	HLRE B,UNAME(J)
	AOJE B,SYSDT5	;NOT LOGGED IN => KILL
	HRLI I,SYSDT9
	PUSHJ P,SYSJEX
	    PUSHJ P,SYSDT3
	POPJ P,

SYSDT5:	HRLI I,[MOVEI I,[ASCIZ / KILLED JOB # /]
		JRST SYSSP]
	PUSHJ P,SYSJEX
	    PUSHJ P,SYSDT6
	POPJ P,

SYSDT6:	PUSHJ P,SYSDT3	;FIRST DETACH (LEAVES USER INDEX OF TOP LEVEL JOB IN A).
	JRST ALOGO6	;THEN LOG OUT.  SINCE DETACHED, NO ADDITIONAL MSG FROM SYSGUN.

;CALL WITH CLOCK OFF TO DETACH THE JOB WITH IDX IN A AND J.
;ASSUME JOB'S BULGOS HAS BEEN CHECKED, AND TREESW LOCKED.
;TURNS CLOCK BACK ON AND DOES A LSWCLR
SYSDT7:	TDZA B,B	;HERE TO LEAVE AROUND
SYSDT3:	 MOVEI B,10	;HERE TO SET BUMRTL WHEN WE DETACH
	PUSHJ P,SOSSET
	    DIELOK(A)
	AOS DIELOK(A)
	CONO PI,CLKON
	MOVEM B,CTLBTS(U)
	PUSHJ P,NDETA0
	 BUG
	POPJ P,

IFN NDLTYS+NETYS,[

;HANDLE DIAL-UP LINE CONNECTS OR DISCONNECTS ON DL-10 AND DTE20.

SYSDIL:
IFN NDLTYS,[
	SKIPN A,DL10CL
	 JRST SYSDL2	;THERE'S NONE TO PROCESS?
	SETZM DL10CL	;FREE THE VAR FOR THE PDP11
	PUSHJ P,SYSDL0
SYSDL2:	];NDLTYS
IFN NETYS,[
	SKIPGE A,DTEHNG
	 JRST SYSDL3
	SETOM DTEHNG
	PUSHJ P,SYSDL0
SYSDL3:
];NETYS
	POPJ P,

SYSDL0:	LDB I,[.BP 77,A] ;GET OUT THE TTY NUMBER
	CAIL I,NCT
	 POPJ P,
	TRNE A,-100
	 JRST SYSDL1	;IT'S A CONNECT
	PUSHJ P,SWTL	;IT'S A DISCONNECT
	    TREESW
	MOVE J,TTYSTS(I) ;DETACH THE TREE ON THAT TTY.
	JUMPL J,LSWPOP	;THERE'S NO TREE.
	TLNN J,%TSCNS
	 JRST LSWPOP	;TTY IS OPEN AS A DEVICE.
	MOVE I,APRC(J)
	TLNE I,BULGOS	;GIVE UP IF TREE LOGGING OUT.
	 JRST LSWPOP
	MOVE U,USER
	MOVEI I,[ASCIZ /DIALUP LINE DISCONNECTED,/]
	JRST SYSDT4

;ON A CONNECT, SNARF THE LINE SPEEDS DETERMINED BY THE PDP11.
SYSDL1:	LDB B,[.BP 7000,A]
	DPB B,[$TTISP,,TTYTYP(I)]
	LDB B,[.BP 700,A]
	DPB B,[$TTOSP,,TTYTYP(I)]
	PUSHJ P,NCNSSP		;SET UP INITIAL TTY TYPE AS PRINTING, ACCORDING TO SPEED
	MOVEI B,20		;DON'T ASSUME TTY IS AT LEFT MARGIN
	MOVEM B,TTYIHP(I)
	MOVEM B,TPHP(TT)
	MOVEM B,TPHP+TPLEN(TT)
	POPJ P,
];NDLTYS+NETYS
.ELSE SYSDIL==CPOPJ

IFN N11TYS,[
SYS11D:	MOVEI I,[ASCIZ /TV 11 WENT DOWN --/]
	PUSHJ P,SYSSTD	;STRING, SPACE, TIME AND CR
	SETZM TT11P	;IN CASE SCR11D WAS SET BY A USER, AND HE DIDN'T HACK THIS.
	MOVEI A,TT11HD+1
	MOVEM A,TT11HD	;PREVENT TT11IN FROM BEING CALLED ANY MORE.
SYS11G:	PUSHJ P,SWTL	;PREPARE FOR DOING DETACHES
	    TREESW
	MOVE I,[-N11TYS,,NF11TY]
SYS11F:	SKIPGE J,TTYSTS(I)	;DETACH ALL 11TV TREES.
	 JRST SYS11E		;THIS 11TV NOT IN USE
	TLNN J,%TSCNS
	 JRST SYS11P		;THIS 11TV IN USE AS A DEVICE, DON'T DETACH BUT DO PCLSR
	MOVE T,APRC(J)
	TLNE T,BULGOS
	 JRST SYS11E		;DON'T DETACH TREES THAT ARE LOGGING OUT.
	MOVE U,USER
	MOVEI I,[ASCIZ / .../]
	PUSHJ P,SYSDT4	;DETACH OR KILL JOB W/ # IN J, AND PRINT MESSAGE.
	JRST SYS11G	;TREESW NOW UNLOCKED; MUST RE-LOCK.

SYS11P:	HRRZ A,J	;PCLSR THE NAME DRAGON
	PUSHJ P,NJRPCL
	PUSHJ P,NJUPCL	;AND DROP INTO SYS11E

SYS11E:	AOBJN I,SYS11F
	PUSHJ P,LSWPOP	;TREESW NOT NEEDED IF NOTHING TO DETACH.
	MOVSI T,-MXVBN	;FLUSH VIDEO BUFFER ASSIGNMENTS.
	SETOM VBAST(T)
	AOBJN T,.-1
	MOVEI T,0
SYS11V:	CAML T,USRHI
	 POPJ P,
	SETZM NVDBA(T)
	SETOM TVCREG(T)	;FLUSH TV BUFFER NUMBERS IN CREGS
	ADDI T,LUBLK
	JRST SYS11V

TVBNCL:	PUSH P,T	;"DEASSIGN" TVVBN(U) AND CLEAR IT ON SCREEN IF NECC
	SKIPN TEN11F
	 SKIPL TT11P
	  JRST TVBNC1
	SKIPL T,TVVBN(U)
	 CAME U,USER
	  JRST TVBNC1
	PUSH P,400000+TTR10*2000
	MOVEM T,400000+TTR10*2000
	MOVE T,TVBLAD
	CLEARM 400000+TTR0*2000(T)
	POP P,400000+TTR10*2000
TVBNC1:	SETOM TVVBN(U)
	JRST POPTJ
];N11TYS

;PRINT CONSOLE FREE MSGS ON ALL TTYS THAT NEED IT.
;NOTE THAT THERE ARE LOWER CASE MESSAGES ON THIS PAGE.
.SEE TTYLO1	;THIS RTN SIGNALLED WHEN A TTY BECOMES FREE.
SYSCFM:	CLEARM IOCHNM+STYOC	;REUSE SYSTEM CONSOLE CHANNEL
SYSCF0:	MOVEI A,0
SYSCF1:	CAIL A,NCT
	 JRST SYSCOP		;DONE, SWITCH SYSCON CHANNEL BACK TO SYSCON
	SKIPGE B,TTYSTA(A)	.SEE %TACFM
	 AOJA A,SYSCF1
	TLNE B,%TANJS
	 TLZ B,%TACTZ		;%TANJS MEANS A FAILED ^Z - FORGET ABOUT THAT ^Z.
	MOVEM B,TTYSTA(A)
	SKIPGE TTYSTS(A)	.SEE %TSFRE
	 TLNE B,%TACTZ
	  AOJA A,SYSCF1		;IN PROCESS OF LOADING TREE FOR THIS CONSOLE
	HRLZ T,A
	ADD T,[%TJDIS+%TJMOR,,TYODN]
	MOVEM T,IOCHNM+STYOC	;"OPEN" A CHANNEL TO THAT TTY.
	SKIPGE SHUTDN
	 PUSHJ P,SYSTS1		;IF SHUTDOWN AND A DISPLAY, CLEAR THE SCREEN
	MOVEI I,[ASCIZ /
Top level interrupt, tree detached
/]
	MOVSI B,%TCDET	;IF TTY FREE DUE TO DETACH FOR TOP LEVEL INT,
	TDNE B,TTYCOM(A)
	 PUSHJ P,SYSSP	.SEE NDETAC	;SAY SO.
	ANDCAM B,TTYCOM(A)
	MOVSI B,%TANJS
	ANDCA B,TTYSTA(A)
	EXCH B,TTYSTA(A)	;CLEAR BIT, SAVE OLD VALUE
	PUSH P,A
	XCT DWNMSG
	SKIPGE SHUTDN
	 JRST SYSCF2		;SYSTEM IS DOWN, SAY SO
	XCT SCMESG
	CAMN A,SYSCN
	 JRST SYSCF2		;SYSTEM JOB USING THIS CONSOLE, SAY SO
	SRITYP [ System fully loaded. Console ]
	TLNN B,%TANJS
	 SRITYP [ Console ]
	PUSHJ P,SYSSP
IFN N11TYS,	CAIE A,NF11TY	;ON ALL FREE PDP11-TV CONSOLES
	 PUSHJ P,SYSOPT
	MOVEI I,[ASCIZ / Free./]
	PUSHJ P,SYSSTD
	XCT DMESSG
	SKIPE SYSDBG
SYSCF2:	 PUSHJ P,SYSSTD	;SAY "SYS BEING DEBUGGED" IF NEC.
	SKIPLE SHUTDN
	 PUSHJ P,SYSSHM	;SAY "SYS GOING DOWN" IF NEC.
	POP P,A
	MOVSI B,%TACFM	;TTY NO LONGER NEEDS CONSOLE FREE MSG.
	IORM B,TTYSTA(A)
IFN N11TYS,PUSHJ P,TTYLO2 ;TELL THE PDP11 THIS TTY IS FREE
	SETZM IOCHNM+STYOC
	JRST SYSCF0

SUBTTL SHUTDOWN

;HANDLE .SHUTDN - PRINT "GOING DOWN" MSGS, ETC.
SYSSHD:	LDB D,[221700,,SHUTLK+1]
	PUSHJ P,SWTL
	    SHUTLK
	MOVEI I,SYSSHM
	TLO I,40
	PUSH P,D
	PUSHJ P,SYALCP
	POP P,D
	IMULI D,LUBLK
	SKIPE D		;SKIP IF LEFT FROM >5 MIN PRINT OUT
	 SKIPN A,UNAME(D)
	  JRST LSWPOP
	MOVEI I,[ASCIZ /CULPRIT = /]
	PUSHJ P,SYSSP
	PUSHJ P,SYSSIX
	MOVE A,JNAME(D)
	PUSHJ P,SYSSIX
	PUSHJ P,SYSTCR
	JRST LSWPOP

;GOING DOWN, WHAT A SHAME
SYSSHM:	SRITYP [GOING DOWN IN ]
	SKIPG SHUTDN
	 SRITYP [REVIVED]
	PUSHJ P,SYSSP
	SKIPG B,SHUTDN
	 JRST SYSSHN
	SUB B,TIME
	IDIVI B,30.	;CONVERT TO SECONDS
	PUSHJ P,RTIME	;CONVERT TO SIXBIT
	MOVE B,A
	PUSHJ P,SYSTCD
SYSSHN:	MOVEI I,[.ASCII /.  /]
	JRST SYSSTD

;AND COME HERE WHEN TIME FOR SYS TO GO DOWN.
;MARK THE SYSTEM "DOWN", START FLAPPING TAPES AND DISKS,
;GUN ALL USERS, ETC. COMPLETION OF GOING DOWN IS DETECTED AT
;SLOW CLOCK LEVEL ("COFFIN").
SYSOUT:	PUSHJ P,CLQDEL
	  DEDBLK
	SETOM DEDTIM	;PREVENT ^Z'S
	.FDELE [SIXBIT/   SYSDOWN  MAIL/ ? 0 ? 0]
	 JFCL
	MOVEI U,LUBLK*2
SYSCK3:	SKIPGE SUPPRO(U)	;LOOK FOR ALL TOP-LEVEL JOBS.
	 SKIPN UNAME(U)
	  JRST SYSCK4
	MOVE T,USTP(U)
	TLNE T,BUSRC
	 JRST SYSCK1
	MOVE T,OPTION(U)	;IS THIS JOB AN EXCEPTION?
	TLNE T,%OPLIV
	 JRST SYSCK4		;YES, LET IT LOG ITSELF OUT
SYSCK1:	PUSHJ P,ALOGOUT		;LOG IT OUT (TELLS IT TO PREPARE ITSELF, SIGNAL SYSGUN)
SYSCK4:	ADDI U,LUBLK
	CAMGE U,USRHI
	 JRST SYSCK3
	SETZ U,
DWNMSG:	SRITYP [NOT IN OPERATION]
	PUSHJ P,SYALCP		;TYPE OUT ON FREE CONSOLES
IFN TPLP, MOVEI A,SCRTPF	;TPLOFF
IFN TPLP, IORM A,SUPCOR
IFN UNSPLP,[	SKIPG TPLFLG
	JRST SYSCK0
	MOVEI A,SCRTPF
	IORM A,SUPCOR
SYSCK0:	
]	MOVE I,QACTB
	IORM I,QMDRO
	MOVSI A,-NQS
SYSCK7:	MOVE I,DCHBT(A)
	SKIPN QACT(A)
	IORM I,QTUTO(A)
	AOBJN A,SYSCK7
IFN NUNITS,[
	MOVEI A,1
SYSUDM:	SKIPL UDIRO(A)
	.UDISMT A,	;DISMOUNT TAPES
	CAIGE A,NUNITS
	AOJA A,SYSUDM
]
	MOVE T,TIME
	MOVEM T,DTHTIM
	SETOM SHUTDN
	PUSHJ P,TTTMNT	;TURN OFF ALL TERMINET MOTORS
	JRST SCOR

SUBTTL SYSTEM CHECKS
;CHECK FOR DEVICES THAT LOSE THE PIA, DEVICES THAT INTERRUPT SPURIOUSLY,
;CLOBBERD LOCATIONS IN MEMORY.

IFE KS10P,[	; KS has no devices to speak of...

SYSCK5:	MOVSI A,-128.
SYSC51:	SKIPL B,DCHNTC(A)
SYSC5A:	 AOBJN A,SYSC51
	JUMPGE A,CPOPJ
	TLNN B,300000
	JRST SYSC5A
	PUSH P,A
	TLZE B,200000
	JRST SYSC52
	PUSHJ P,SYSC5S
	JRST SYSC53
SYSC52:	PUSHJ P,SYSC5C
SYSC53:	POP P,A
	MOVSI B,300000
	ANDCAM B,DCHNTC(A)
	JRST SYSC5A

SYSC5C:	PUSHJ P,SYSC5B
	MOVEI I,[ASCIZ / CLOBBERED/]
	JRST SYSSTD

SYSC5S:	PUSHJ P,SYSC5B
	MOVEI I,[ASCIZ / SUSPECTED OF INTERRUPTING ON CHANNEL /]
	PUSHJ P,SYSSP
	LDB T,[360300,,DCHNTC(A)]
	PUSHJ P,SYSSOP
	JRST SYSTCR

SYSSOP:	PUSH P,A
	PUSH P,B
	MOVE A,T
	PUSHJ P,SYSOPT
	JRST POPBAJ

SYSC5B:	MOVEI I,[ASCIZ /DEVICE /]
	PUSHJ P,SYSSP
	HRRZ T,A
	LSH T,2
	PUSHJ P,SYSSOP
	MOVEI I,[ASCIZ / (CONI= /]
	PUSHJ P,SYSSP
	HRRZ T,DCHNTC(A)
	PUSHJ P,SYSSOP
	MOVEI I,[ASCIZ /) /]
	JRST SYSSP

] ;IFE KS10P

SYSCKS:	HRRZ T,UPDBR1		;CHECK FOR CLOBBERED DBRS
	HRRZ TT,UPDBR2
	CAIN T,UPGMP
	 CAIE TT,UPGMP+100
	  BUG HALT,[PAGER DATA CLOBBERED.  MAY BE DEC-TTL LEVEL CONVERTERS LOSING.]
;DROPS THROUGH
;DROPS IN
	MOVE A,SYSCKP
	MOVE B,(A)
	MOVEI C,(B)
	EQV C,(B)
	AOBJN B,.-1
	CAME C,CKSUMS-TSTB(A)
	JRST SYSKS2
	AOBJN A,SYSKS1
SYSKS3:	MOVE A,[-LTSTB,,TSTB]
SYSKS1:	MOVEM A,SYSCKP
	POPJ P,

SYSKS2:	EXCH C,CKSUMS-TSTB(A)
	XOR C,CKSUMS-TSTB(A)	;SAVE XOR
	PUSHJ P,WARMTTY
	PUSHJ P,DINGTTY
	MOVEI I,[ASCIZ /SYSTEM CLOBBERED BETWEEN /]
	PUSHJ P,SYSSP
	HRRZ A,(A)
	PUSHJ P,SYSOPT
	MOVEI I,[ASCIZ / AND /]
	PUSHJ P,SYSSP
	MOVE B,SYSCKP
	HLRE A,(B)
	SETCMM A	;OFFSET BY ONE
	ADD A,(B)
	HRRZS A
	PUSHJ P,SYSOPT
	MOVEI I,[ASCIZ / XOR= /]
	PUSHJ P,SYSSP
	MOVE A,C
	PUSHJ P,SYSFWP
	MOVEI I,[ASCIZ / !/]
	PUSHJ P,SYSSTD
	CLEARM TCKXOR	;TRY TO DETERMINE EXACT ADR AND PREV CONTENTS
	MOVE A,[TCKXOR,,TCKXOR+1]
	BLT A,TCKXOR+35.
	MOVE A,[-LTSTB,,TSTB]
SYSKS6:	MOVE B,(A)
SYSKS5:	MOVE C,(B)
REPEAT 36.,[IFL .RPCNT-18.,TLNE C,400000_<-.RPCNT>
IFGE .RPCNT-18.,TRNE C,400000_<18.-.RPCNT>
	XORM B,TCKXOR+.RPCNT
	]
	AOBJN B,SYSKS5
	AOBJN A,SYSKS6
	MOVSI D,-36.
SYSKS7:	MOVE A,TCKXOR(D)	;UPDATE CKXORS TBL AND FILL TCKXOR TBL WITH POSSIBLE ADRS
	EXCH A,CKXORS(D)
	XOR A,CKXORS(D)
	HRRZM A,TCKXOR(D)
	AOBJN D,SYSKS7
	PUSHJ P,STYOT	;INDENT LINE
	MOVSI D,-36.
	MOVSI E,400000	;CURRENT BIT
	CLEARB I,J	;COUNT OF #'S PRINTED, CLOBBERED WD
SYSKS8:	SKIPE A,TCKXOR(D)
	AOJA J,SYSKS9	;INCR COUNT OF ADRS PRINTED
SYSKT2:	LSH E,-1
	AOBJN D,SYSKS8
	SOJN J,SYSKT1	;MORE THAN 1 ADR CLOBBERD SO CANT PRINT PREV CONTENTS
	MOVEI T,"=
	PUSHJ P,STYO
	MOVE A,I	;PRINT CONTENTS PRIOR TO CLOBBERAGE
	XOR A,(R)	;XOR CURRENT CONTENTS
	PUSHJ P,SYSFWP
	MOVEI T,"-
	PUSHJ P,STYO
	MOVEI T,">
	PUSHJ P,STYO
	MOVE A,(R)
	PUSHJ P,SYSFWP	;CURRENT CONTENTS
SYSKT1:	PUSHJ P,SYSCRF
	JRST SYSKS3

SCKX1:	PUSH P,T	;UPDATE CKXORS TO REFLECT CHANGING WD IN T IN ADR IN Q
	MOVSI C,-36.
SCKX2:	SKIPGE T
	XORM Q,CKXORS(C)
	LSH T,1
	AOBJN C,SCKX2
	JRST POPTJ

SYSKS9:	PUSHJ P,SYSOPT
	PUSHJ P,STYOS
	MOVE R,TCKXOR(D)	;CLEAR DUP ENTRIES
	MOVE T,D
	MOVE Q,E	;ALSO LEAVE LAST ADR IN R (IN CASE ITS ONLY ADR)
SYSKT3:	CAME R,TCKXOR(T)
	JRST SYSKT4
	CLEARM TCKXOR(T)
	XORM Q,I
SYSKT4:	LSH Q,-1
	AOBJN T,SYSKT3
	JRST SYSKT2

SUBTTL SUPPORT ROUTINES FOR BUG MACRO

;NOTE: THESE REPLACE THE SYSMSG ROUTINE THAT USED TO BE HERE

;ENTRY POINTS
BUGCHK:	PUSH P,TT
	MOVE TT,SYSMPT		;HOW MANY MESSAGES BEHIND?
	SUB TT,SYSMPU
	CAIGE TT,<8_SYSMLNG>-8
	 SKIPE SYSDBG
	  JRST BUGPSE+1		;TREAT AS BUGPSE IF BUFFER FULL OR SYSDBG
	CAIA
BUGINF:	 PUSH P,TT
	PUSHJ P,SYSMS0		;HAND MESSAGE TO SYSTEM JOB TO BE PRINTED
	JRST POPTTJ		;CONTINUE TRAPPED ROUTINE

BUGPSE:	PUSH P,TT
	PUSHJ P,SYSMS0		;COPY MESSAGE INTO SYSTEM JOB BUFFER
	JSP TT,BUGDD0		;PRINT MESSAGE AND GO TO DDT
	    ASCIZ/PAUSE.  FIND A WIZARD, CONSIDER TAKING A CRASH DUMP,
OR TYPE <ALTMODE>P TO ATTEMPT TO REVIVE THE SYSTEM./

BUGDDT:	PUSH P,TT
	PUSHJ P,SYSMS0		;COPY MESSAGE INTO SYSTEM JOB BUFFER
	JSP TT,BUGDD0		;PRINT MESSAGE AND GO TO DDT
	    ASCIZ/DDT.  TYPE <ALTMODE>P TO CONTINUE./

BUGNIL:	PUSH P,TT
	JRST BUGHL1		;NO MESSAGE, JUST GO STRAIGHT TO DDT.

BUGAWF:	0			;JSR HERE WHEN AWFUL THINGS HAVE HAPPENED
	CONO PI,PIOFF		;BETTER DO THIS AS SOON AS POSSIBLE
	MOVEM P,BUGACS+P	;SAVE P AND GET A PDL TO USE
	MOVE P,BUGPDL
	PUSH P,BUGAWF		;SIMULATE PUSHJ P,BUGHLT
BUGHLT:	PUSH P,TT
	PUSHJ P,SYSMS0		;COPY MESSAGE INTO SYSTEM JOB BUFFER
BUGHL1:	JSP TT,BUGDD0		;PRINT MESSAGE AND GO TO DDT
	    ASCIZ/HALT.  FIND A WIZARD OR CONSIDER TAKING A CRASH DUMP.
THE SYSTEM HAS CRASHED AND CANNOT BE REVIVED WITHOUT EXPERT ATTENTION.
IF YOU CAN'T FIND HELP, RELOAD THE SYSTEM./

;ROUTINE TO PICK UP THE DATA OUT OF THE BUG TABLE, EVALUATE THE
;ARGUMENTS, AND DUMP THE RESULTS INTO THE SYSMSG BUFFER TO BE
;PRINTED LATER.  THE THIRD THING DOWN ON THE STACK IS THE PC+1
;AT WHICH THE BUG WAS DETECTED.  TT IS THE ONLY SMASHABLE REGISTER.
SYSMS0:	MOVEI TT,8		;8 WORDS IN ENTRY
	ADDB TT,SYSMPT		;UPDATE STORING POINTER
	ANDI TT,8_SYSMLNG-1	;MASK TO BUFFER INDEX
	ADDI TT,SYSMBF
	PUSH P,TT		;SAVE PTR
	PUSH P,A		;NOW LOCATE BUG TABLE ENTRY
	PUSH P,B
	MOVE A,TIME		;STASH TIME IN EXTRA WORD OF ENTRY
	MOVEM A,7(TT)
	MOVEI B,BUGTAB
SYSMS1:	HRRZ A,(B)
	CAIN A,@-5(P)
	 JRST SYSMS2		;PC MATCHES
	HLRZ A,(B)		;ADVANCE TO NEXT ENTRY
	ADD B,A
	JUMPN A,SYSMS1
	JRST 4,.		;NOT IN TABLE?? MACROS MUST BE SCHROD

SYSMS2:	HLRZ A,(B)
	ADDI TT,-2(A)
	EXCH TT,-2(P)		;TT START OF ENTRY, -2(P) END
	MOVE A,TT
	HRLI A,1(B)		;COPY BITS,,STRING AND ARG POINTERS
	BLT A,@-2(P)
	POP P,B
	POP P,A
	SUBM TT,(P)		;(P) GETS -NARGS
	SKIPE (P)		;IN CASE NO ARGS
SYSMS3:	 PUSH TT,@1(TT)		;EVALUATE ARGUMENT POINTERS
	AOSGE (P)
	 JRST SYSMS3
	MOVEI TT,SCRMSG		;BIT FOR MSG PRINT
	IORM TT,SUPCOP		;TRY EVERY SECOND TO PRINT SOME MSGS
	IORM TT,SUPCOR		;FIRST ATTEMPT RIGHT AWAY.
	JRST POP1J		;RETURN TO BUGINF OR WHEREVER

;CALL HERE TO PRINT THE MESSAGES OUT OF THE BUFFER
;A HAS SCRMSG
SYSMPR:	MOVE TT,SYSMPT		;LAST MESSAGE IN
	CAMG TT,SYSMPU		;LAST MESSAGE OUT
	 JRST [	ANDCAM A,SUPCOP	;CAUGHT UP
		POPJ P, ]
	SUBI TT,8_SYSMLNG
	CAMLE TT,SYSMPU
	 JRST [	MOVE A,TT	;BEHIND BY MORE THAN SIZE OF BUFFER
		SUB A,SYSMPU
		MOVEM TT,SYSMPU
		LSH A,-3	;NUMBER OF MESSAGES LOST
		PUSHJ P,DINGTTY
		PUSHJ P,SYSDPT
		MOVEI I,[ASCIZ/ SYS MSGS LOST/]
		PUSHJ P,SYSSTD
		JRST .+1 ]
	MOVEI TT,8
	ADDB TT,SYSMPU
	ANDI TT,8_SYSMLNG-1
	ADDI TT,SYSMBF
	PUSHJ P,DINGTTY
	HLLZ D,(TT)		;GET MODE FLAGS
	HRRZ I,(TT)		;GET ASCIZ MSG
	HRLI I,440700
SYSMP0:	ILDB T,I
	JUMPE T,SYSMP1
	CAIGE T,10
	 JRST SYSMP3
	PUSHJ P,STYO
	JRST SYSMP0

SYSMP1:	PUSHJ P,STYOS		;SPACE AND OUTPUT REMAINING ARGS
	PUSHJ P,SYSMP2
	 JRST SYSTCR		;END WITH TIME, POPJ
	JRST SYSMP1

SYSMP3:	PUSH P,T		;OUTPUT THIS MANY ARGS
SYSMP4:	PUSHJ P,SYSMP2
	 JFCL
	PUSHJ P,STYOS
	SOSLE (P)
	 JRST SYSMP4
	SUB P,[1,,1]
	JRST SYSMP0

SYSMP2:	MOVEI C,0
	LSHC C,3		;GET A BYTE
	JUMPE C,CPOPJ		;NO MORE ARGS TO PRINT
	PUSH P,I
	MOVE A,1(TT)
	PUSHJ P,@SYSMTB(C)
	POP P,I
	AOJA TT,POPJ1

;DISPATCH TABLE FOR SYSTEM MESSAGE PRINTER

SYSMTB:	JRST 4,.	;0 CHECKED FOR END
	SYSFWP		;1 FULL WORD OCTAL
	SYSDPT		;2 FULL WD DECIMAL
	SYSDPC		;3  " WITH COMMAS
	SYSCRF		;4 DO CR
	CPOPJ		;5 ?
	SYSIXP		;6 SIXBIT
	[MOVE I,A	;7 ASCIZ
	 JRST SYSSP]

;ROUTINE FOR BUGS THAT NEED TO HALT INTO DDT
BUGDD0:	HRLI TT,440700
	CONO PI,PIOFF		;PREVENT INTERFERENCE, AND HACK STYO
	MOVEM TT,T00POS		;SAVE ADDRESS OF MESSAGE TEMPORARILY
	POP P,TT		;RESTORE TT AT TIME OF BUG
	POP P,BUGPC		;ADDRESS+1 OF BUG
	SKIPE BUGAWF
	 MOVE P,BUGACS+P	;CORRECT P AT TIME OF BUG
	SETZM BUGAWF		;CLEAR FLAG FOR NEXT BUG IN CASE REVIVED
	CONI PI,BUGPI		; SAVE PI STATUS
	CONI BUGAPR		; SAVE APR STATE
IFE KA10P,[
	CONI PAG,BUGEBR		; SAVE EBR, UBR, ETC
	DATAI PAG,BUGUBR
] ;IFE KA10P
	SPM BUGPGM		; SAVE PAGER STATE
	MOVEM 17,BUGACS+17	;SAVE ACS
	MOVEI 17,BUGACS
	BLT 17,BUGACS+16
	MOVE P,BUGPDL		;USE THIS PDL FOR TYPING OUT
	PUSH P,T00POS		;RECOVER ASCIZ STRING FOR FLAVOR OF BUG
	PUSHJ P,SYSCRF		;CARRIAGE RETURN
BUGDD1:	MOVEI A,SCRMSG
	PUSHJ P,SYSMPR		;DUMP SYSMSG BUFFER
IFN KA10P,[
	CONSZ TTY,40		;PUNT IF CHARACTER TYPED
	 JRST BUGDD2
] ;KA10P
IFN KL10P,[
	SETZM DTEFLG
	MOVEI A,%DTTYI
	MOVEM A,DTECMD
	CONO DTE,%DBL11
	SKIPN DTEFLG
	 JRST .-1
	SKIPE DTEF11		;INPUT TYPED?
	 JRST BUGDD2		;YES, PUNT
] ;KL10P
IFN KS10P,[
	SKIPE 8CTYIN		; Any input available?
	 JRST BUGDD2		; Yes:  Punt.
] ;KS10P
	MOVE TT,SYSMPT		;LAST MESSAGE IN
	CAMLE TT,SYSMPU		;LAST MESSAGE OUT
	 JRST BUGDD1
BUGDD2:	MOVE A-1,BUGPI		;CHECK FOR PI IN PROGRESS
	ANDI A-1,77400
	LSH A-1,20.
	JFFO A-1,[ MOVEI I,[ASCIZ/PI LEVEL /]
		   PUSHJ P,SYSSP
		   PUSHJ P,SYSDPT
		   PUSHJ P,STYOS
		   JRST .+1 ]
	MOVEI I,[ASCIZ/BUG/]
	PUSHJ P,SYSSP
	POP P,I			;PAUSE OR HALT MESSAGE
	SKIPN SYSDBG		;PUNT LONG-WINDED MESSAGE IF DEBUGGING
	 PUSHJ P,SYSSP
	MOVEI I,[ASCIZ/
YOU ARE NOW IN DDT./]
	PUSHJ P,SYSSP
	MOVEI TT,[ASCIZ|BUGPC/Q-2/|]
	HRLI TT,440700
	MOVEM TT,777777		;TELL DDT TO EXAMINE BUGHLT ADDRESS
	MOVE TT,BUGPC		;ARRANGE FOR <ALT>P TO JUMP THERE
	MOVEM TT,@DDT-6		;IN OLDER DDT WILL JUST CLOBBER AC0
	MOVSI 17,BUGACS		;RESTORE ACS
	BLT 17,17
	CONO PI,PION
	JRST DDT

EBLK

;DATA AREAS POINTERS AND BUFFER FOR SYS MSG PRINTER

CTLMAX==55.	;Number of lines after which we should print the date.
CTLCNT:	0	;Keeps track of number of lines printed on console.

SYSMPT:	0	;POINTER TO MESSAGE MOST RECENTLY INSERTED
SYSMPU:	0	;POINTER TO MESSAGE MOST RECENTLY PRINTED
		;(MUST TAKE MODULO LENGTH OF TABLE, AND ADD OFFSET OF BEGIN OF TABLE)
IFNDEF SYSMLNG,SYSMLNG==5	;LOG(2) OF # ENTRIES (5=>32)

SYSMBF:	BLOCK 8_SYSMLNG	;8 WDS PER ENTRY: BITS,,STRING, 6 ARGS, TIME

BUGPC:	0			;RESTART PC FROM BUG
BUGPI:	0			; CONI PI,BUGPI
BUGAPR:	0			; CONI APR,BUGAPR
IFE KA10P,[
BUGEBR:	0			; CONI PAG,BUGEBR
BUGUBR:	0			; DATAI PAG,BUGUBR
] ;IFE KA10P
BUGPGM:	BLOCK UPGMLE-UPGML	; SPM BUGPGM
BUGACS:	BLOCK 20		;AC SAVE AREA FOR BUGDD0
BUGPDL:	-20,,.
	BLOCK 20
T00POS:	0			;TTY00 HORIZONTAL POSITION

BBLK

SUBTTL .SETLOC ROUTINE (DOCUMENT THEN DOES IT)

SYSSET:	MOVE A,SETSLC	;LOCATION TO BE MODIFIED
	TLNN A,-1	;SKIP IF ALREADY DONE
	 SKIPA C,SETSLQ	;NEW VAL IN SETSLQ
	  SKIPA C,(A)	;NEW VAL IN LOC
	   SKIPA D,A	;OLD VAL IN @A
	    MOVEI D,SETSLQ	;OLD VAL IN SETSLQ
	PUSHJ P,SYSSCT	;PRINT OUT DDT-TYPE SEQUENCE
	MOVE A,SETSU	;GET USET NAME
	PUSHJ P,STYOT	;TYPE OUT A TAB
	MOVEI B,0
	PUSHJ P,SYSIXP	;PRINT NAME OF GUILTY PARTY
	PUSHJ P,SYSTCR	;STANDARD SYS CARRIAGE RETURN
	SKIPGE SETSLC	;IF ALREADY MUNGED AT UUO LEVEL
	 POPJ P,	;THEN EXIT NOW
	MOVE T,SETSLQ	;GET DESIRED VALUE
;	SKIPL UMBTS
;	 JRST SYSSE8	;DON'T HACK METABITS
;	LMB Q,@SETSLC	;GET META BIT OF DESIRED LOCATION
;	TRNE Q,1	;IF 1 THEN HAVE TO MOMENTARILY CLEAR IT
;	 JRST SYSSE5
SYSSE8:	EXCH T,@SETSLC	;META BIT=0, CHANGE LOCATION
SYSSE6:	MOVE Q,SETSLC	;GET ADR OF MUNGED LOC
	MOVE A,[-LTSTB,,TSTB]
SYSSE1:	MOVE B,(A)
	CAIGE Q,(B)
	 JRST SYSSE3
	HLRE C,B
	SETCMM C
	ADD C,B
	CAILE Q,(C)
	 JRST SYSSE3
	PUSHJ P,SCKX1	;UPDATE CKXORS TBL TOO
	EQV T,@SETSLC
	EQVM T,CKSUMS-TSTB(A)
	MOVE T,@SETSLC
	PUSHJ P,SCKX1	;UPDATE TO REFLECT NEW CONTENTS
SYSSE2:	MOVSI A,SCLSET
	ANDCAM A,SUPCOR
	CAIE Q,SYSDBG	;IF NOT DEBUG SWITCH
	 POPJ P,	;EXIT
	PUSHJ P,DBGINT	;SYSDBG STATE CHANGE, TELL ALL USERS
	SKIPE SYSDBG
	 JUMPN T,CPOPJ
;SYSDBG CLEARED, GIVE "IN OPERATION" MESSAGE BY DROPPING INTO ISYS
;HERE WHEN SYSTEM IS UP AND DISKS HAVE BEEN INITIALIZED
;RE-ENTER HERE WHEN SYSDBG STATE CHANGED
ISYS:	PUSHJ P,DATIME	;MAY BE ABLE TO FIND TIME IMMEDIATELY (ONCE MFD IN)
	PUSHJ P,TTTMN2	;MAKE SURE WE THINK THAT ALL TERMINET
		;MOTORS ARE OFF, SO WE'LL TRY TO TURN THEM ALL ON WHEN WE TYPE
		;"ITS IN OPERATION" ON THEM.
	PUSHJ P,TTRSAL	;SEND %TDORS TO ALL SOFTWARE TTYS
	SRITYP [IN OPERATION]
	SKIPE SYSDBG	;IF SYS IN DEBUG MODE
DMESSG:	 SRITYP [BEING DEBUGGED]	;SET TO APPROP MSG
	PUSHJ P,SYALCP	;PRINT ON ALL CONSOLES
SCMESG:	SRITYP [SYSTEM JOB USING THIS CONSOLE.]
	PUSHJ P,SYSSP	;PRINT ON SYS JOB CONSOLE
	SKIPGE DMLLDF	;START DRAGON (DAEMON) IF WANTED
	 SKIPL DMON+1	;AND NOT DONE ALREADY
	  POPJ P,
	HRROI T,DMON
	CONO PI,UTCOFF
	PUSHJ P,NUJBST
	 BUG		;SHOULD BE ROOM IN REQUEST BUFFER
	JRST UTCONJ

SYSSE3:	AOBJN A,SYSSE1
	JRST SYSSE2

		;SETLOC ROUTINE TO MODIFY LOCATION WITH META BIT = 1

;SYSSE5:	MOVEI D,0
;	SMB D,@SETSLC
;	EXCH T,@SETSLC
;	SMB Q,@SETSLC
;	JRST SYSSE6

SUBTTL MEMORY ERROR MESSAGES

NXMTYP:	MOVEI I,[ASCIZ /NON-EX MEM ERROR #/]
	MOVEI TT,1
	JRST MEMTYP

IFE KA10P,[
BPFTYP:	MOVEI I,[ASCIZ /PAGE FAIL ERROR #/]
	MOVEI TT,2
	JRST MEMTYP
] ;IFE KA10P

PARTYP:	MOVEI I,[ASCIZ /PARITY ERROR #/]	;PARITY ERROR
	MOVEI TT,0
MEMTYP:	PUSHJ P,SYSSP
	MOVE A,PARERR(TT)
	PUSHJ P,SYSOPT
	MOVEI I,[ASCIZ /,  PC = /]
	PUSHJ P,SYSSP
	MOVE A,PARPC(TT)
	PUSHJ P,SYSFWP
	MOVEI I,[ASCIZ /,  JOB # /]
	PUSHJ P,SYSSP
	MOVE A,PARUSR(TT)
	IDIVI A,LUBLK
	PUSHJ P,SYSOPT
	MOVEI I,[ASCIZ /, USR:/]
	PUSHJ P,SYSSP
	MOVE D,PARUSR(TT)
	MOVE A,UNAME(D)
	PUSHJ P,SYSSIX
	PUSHJ P,STYOS
	MOVE A,JNAME(D)
	PUSHJ P,SYSSIX
	JRST @.+1(TT)	;DISPATCH ON TYPE OF ERROR
	 PARTY2		;PARITY
	 SYSTCR		;NXM
IFE KA10P,[
	 BPFTY2		;BPF

BPFTY2:	MOVEI I,[ASCIZ /, PFW = /]
	PUSHJ P,SYSSP
	MOVE A,BPFPFW
	PUSHJ P,SYSFWP
	JRST SYSTCR
] ;IFE KA10P

PARTY2:	PUSHJ P,SYSTCR
IFN KS10P,[
	MOVEI I,[ASCIZ /ERR ADDR = /]
	PUSHJ P,SYSSP
	MOVE T,PARERA		; Error address is all we collect on the KS.
	PUSHJ P,SYSP
	PUSHJ P,SYSCRF
] ;KS10P
IFN KL10P,[
	SKIPN PARRSN
	 JRST PARTP1
	MOVEI I,[ASCIZ /ERR ADDR = /]
	PUSHJ P,SYSSP	;PAR ERR INT ALWAYS GIVES ERR ADDR
	MOVE T,PARERA
	JRST PARTP2

PARTP1:	MOVEI I,[ASCIZ /PFW = /]
	PUSHJ P,SYSSP	;PAR ERR TRAP GIVES PFW AND BAD DATA
	MOVE T,PARPFW	;EVEN IF SCAN DOESN'T FIND PAR ERRS.
	PUSHJ P,SYSP
	MOVEI I,[ASCIZ /,  BAD DATA = /]
	PUSHJ P,SYSSP
	MOVE T,PARWRD
PARTP2:	PUSHJ P,SYSP
	PUSHJ P,SYSCRF
] ;KL10P
	SOSGE D,PARCNT
	 POPJ P,
	JUMPE D,PARTP3	;IF SCAN FOUND MORE THAT ONE PAR ERR,
		;PRINT AND'S AND OR'S OF DATA AND ADDRS.
IRP X,,[PARAAN,PARAOR,PARAND,PARIOR]Y,,[ADDR AND,ADDR IOR,DATA AND,DATA IOR]
IFE .IRPCNT&1,	MOVEI I,[ASCIZ /Y = /]
.ELSE		MOVEI I,[ASCIZ /,  Y = /]
		PUSHJ P,SYSSP
		MOVE T,X
		PUSHJ P,SYSP
IFN .IRPCNT&1,	PUSHJ P,SYSCRF	;PRINT TWO ITEMS PER LINE.
TERMIN
PARTP3:	MOVEI I,[ASCIZ /PARITY ERRORS:
/]
	PUSHJ P,SYSSP
SYSPR1:	PUSHJ P,STYOT	;TYPE TAB
	MOVE A,PARADR(D)
	PUSHJ P,SYSFWP
	PUSHJ P,STYOT
	MOVE A,PARCON(D)
	PUSHJ P,SYSFWP
	PUSHJ P,SYSCRF
	SOJGE D,SYSPR1
	AOS D,PARCNT
	MOVEI I,[ASCIZ/ .../]
	CAIN D,MXPARS
	 PUSHJ P,SYSSP	;NOT ALL PARITY ERRORS WERE PRINTED
	JRST SYSCRF

SUBTTL LOGIN & MISCELLANEOUS MESSAGES

SYSLGI:	SKIPE SUPPLG
	 POPJ P,		;DON'T BOTHER PRINTING MESSAGE
	HLRZ I,SLGIV+1		;Message (CHUNAME, LOGIN, etc)
	PUSHJ P,SYSSP
	MOVEI TT,SLGIV	;.LOGIN
	MOVE A,(TT)
	CAMN A,[-1]
	 BUG
	PUSHJ P,SYSG23
	SKIPE A,SLGIV+2
	PUSHJ P,SYSSIX
	JRST SYSTCR

SYSG23:	PUSHJ P,SYSIXP
	PUSHJ P,STYOS
	HRRZ A,1(TT)	;PICK UP TTY NUM
	JRST SYSOPT

;PRINT A MESSAGE WHEN SOMEONE WRITES ON SYS.
SYSWRT:	MOVE A,SWUNAM	;WRITE ON SYS DEVICE
	PUSHJ P,SYSIXP
	MOVE A,SWJNAM
	PUSHJ P,SYSSIX
	MOVE A,SWFN3	;SNAME - SYS,SYS1, ...
	PUSHJ P,SYSSIX
	MOVE A,SWFN1
	PUSHJ P,SYSSIX
	MOVE A,SWFN2
	PUSHJ P,SYSSIX
	MOVE A,[SIXBIT /WRITE/]		;Assume luser was writing.
	MOVE B,SWMOD			;Check opcode.
	CAIN B,2			;MLINK?
	 MOVE A,[SIXBIT /LINK/]		; Yup.
	CAIN B,4			;Maybe DELE/WO, RENAM/WO?
	 MOVE A,[SIXBIT /DELRNM/]	; Yah, hmmhmmm.
SYSWR3:	PUSHJ P,SYSSIX
	JRST SYSTCR

SUBTTL DETERMINE AND PRINT THE DATE AND TIME

EBLK
DATIME:	JRST .+1	;RH MODIFIED TO REFLECT PROGRESS
BBLK		;ROUTINE CALLED BY PUSHJ,
		;BIT SET EVERY SECOND FROM SUPCOP UNTIL
		;THE DATE IS KNOWN.
	MOVSI T,40000	;"MFD IN" BIT IN QMDRO
	CONO PI,UTCOFF	;DISABLE INTERRUPTS
	TDNE T,QMDRO	;SEE IF DIRECTORY IN
	 JRST UTCONJ	;NOT IN
		;MFD IN, GET CRUD FROM IT
	MOVE A,QMDRO	;GET ORIGIN OF MFD
	SKIPE B,MDYEAR(A)	;YEAR
	 MOVEM B,FYEAR
	SKIPE C,MPDOFF(A)	;PDTIME OFFSET
	 MOVEM C,PDTIME
	MOVEI C,DATIM0
	HRRM C,DATIME
	JRST UTCONJ

DATIM0:	PUSHJ P,GLPDTM	;NOW SEE IF IT'S ALL THERE
	 JRST DATIM2	;NOT ALL THERE, DOCUMENT WHAT'S MISSING
	JRST DATIM6	;ALL THERE, TYPE OUT AND CLEAR SUPCOR BIT

		;NOT ALL THERE, DOCUMENT (TYPE OUT) WHAT IS MISSING
		;SHOULD NOT BE NECESSARY TO WARM UP TTY

DATIM2:
IFN PDCLKP,[
	DATAI PDCLK,A	;SEE IF CLOCK ON
	JUMPN A,DATIM3	;JUMP IF CLOCK WINNING
	MOVEI I,[ASCIZ /DECORIOLIS CLOCK HAS BEEN POWERED OFF, IF THE TIME
CANNOT BE DETERMINED FROM THE NETWORK, YOU MAY HAVE TO :PDSET
/]
	MOVEI T,500.
	SOJG T,.	;WAIT AND BE SURE
	DATAI PDCLK,A	;GET DATAI AGAIN
	JUMPN A,DATIM3	;JUMP IF OK NOW
	PUSHJ P,SYSSP	;COMPLAIN
] ;PDCLKP
IFN KS10P,[
	RDTIM A		; Clobbers B
	TLC A,1729.	; "A most interesting number"
	TLNN A,-1	; If present, KS-10 clock still remembers the time.
	 JRST DATIM3
	MOVEI I,[ASCIZ /THE KS-10 CLOCK HAS BEEN RESET, IF THE TIME CANNOT
BE DETERMINED FROM THE NETWORK, YOU MAY HAVE TO :PDSET
/]
	PUSHJ P,SYSSP	; Complain
] ;KS10P
DATIM8:
;	HRROI T,CCTSS	;NOW PREPARE TO LOAD CTSS CALLER FROM SYS:@ CCTSS
;	PUSHJ P,NUJBST	;DO A PSEUDO-CONTROL Z
;	JRST DATIM7
DATIM3:	MOVEI C,0	;COUNTER OF THINGS MISSING FROM MFD
	MOVEI I,[ASCIZ /YEAR, /]
	SKIPG FYEAR	;CHECK YEAR
	PUSHJ P,[AOJA C,SYSSP]	;NOT IN, COMPLAIN
IFN PDCLKP\KS10P,[
	MOVEI I,[ASCIZ /PDTIME OFFSET, /]
	SKIPN PDTIME
	PUSHJ P,[AOJA C,SYSSP]	;PDTIME OFFSET NOT IN
] ;PDCLKP\KS10P
	JUMPE C,DATIM4	;SKIP FOLLOWING IF EVERYTHING ON DISK
	MOVEI I,[ASCIZ /NOT ON DISK.
PLEASE SETLOC APPROPRIATELY.
/]
	PUSHJ P,SYSSP
DATIM4:	SKIPA T,[DATIM5];UPDATE DATIME TO WAIT FOR EVERYTHING TO BE THERE
DATIM7:	MOVEI T,DATIM8	;UPDATE DATIME TO WAIT FOR ABILITY TO DO
			; PSEUDO-CONTROL Z FOR CTSS CALLER
	HRRM T,DATIME
	POPJ P,

	;WAIT FOR EVERYTHING TO BE THERE
	;THEN TYPE OUT "IT IS NOW...", ETC.

DATIM5:	PUSHJ P,GLPDTM	;CHECK IT
	 POPJ P,		;NOT ALL THERE YET
	MOVEI T,DATIME+1	;ALL THERE, RE-INITIALIZE DATIME
	HRRM T,DATIME
DATIM6:	MOVSI T,SCLDAT	;STOP CALLING DATIME EVERY SECOND
	ANDCAM T,SUPCOP	;NOW THAT THE WORK IS DONE.
	HRRZS TIMOFF	;START UP SLOW CLOCK REAL-TIME ROUTINE
	SETZM RSWTIM	;Initialize the resource-warning timestamp.
	PUSHJ P,WARMTT	;WARM UP TTY
	PUSHJ P,RYEAR1	;GET DAY OF WEEK IN RELEVANT FIELD OF E
SYSNWP:	MOVEI I,[ASCIZ /IT IS NOW /]
	PUSHJ P,SYSSP	;TYPE IT OUT
	IDIVI A,SPD	;A HAS RESULT OF PUSHJ TO GLPDTM
	PUSH P,A	;SAVE DAY OF YEAR
	MOVE A,B	;GET # SECS SINCE MIDNIGHT IN A
	IDIVI A,SPD/2	;GET AM/PM BIT IN A, 12 HOUR TIME (SECS) IN B
	PUSH P,[SIXBIT / AM    PM/](A)	;REMEMBER WHAT HALF-DAY
	CAIGE B,3600.	;USE 12:01 RATHER THAN 0:01 IN 12-HR TIME.
	 ADDI B,12.*3600.
	PUSHJ P,RTIME	;CONVERT TIME TO SIXBIT
	MOVE B,A
	TLNN B,170000	;IF LEADING DIGIT IS ZERO,
	TLZ B,770000	;THEN TURN IT INTO A BLANK
	PUSHJ P,SYSTCD	;TYPE OUT TIME
	POP P,B		;RESTORE AM OR PM WORD
	PUSHJ P,SYS6	;TYPE IT OUT
	MOVE B,[SIXBIT / EST,/]
	TLNE E,100000	;DST BIT
	HRLI B,(SIXBIT / ED/)	;DAYLIGHT SAVINGS TIME, TYPE OUT EDT INSTEAD OF EST
	PUSHJ P,SYS6	;TYPE IT OUT
	PUSHJ P,STYOS	;TYPE A SPACE
	LDB B,[320300,,E]	;GET DAY OF WEEK (0 => SUNDAY)
	MOVE B,DOWTBL(B)	;MON, TUES, WEDNES, ETC. (IN SIXBIT)
	PUSHJ P,SYS6	;TYPE IT OUT
	MOVEI I,[ASCIZ /DAY, /]	;FINISH ON DAY OF WEEK
	PUSHJ P,SYSSP	;" " "
	POP P,A		;RESTORE DAY OF YEAR
	PUSHJ P,RDATE1	;CALCULATE MONTH AND DAY
	MOVE B,NMNTBL-1(B)	;GET SIXBIT FOR MONTH
	PUSHJ P,SYS6	;TYPE OUT MONTH
	PUSHJ P,STYOS	;TYPE A SPACE
	MOVE A,C	;GET DAY OF MONTH IN A
	PUSHJ P,SYSDPT	;TYPE OUT IN DECIMAL
	MOVEI T,",
	PUSHJ P,STYO	;TYPE A COMMA
	MOVEI A,(E)	;GET YEAR
	PUSHJ P,SYSDPT	;TYPE IT OUT
	JRST SYSCRF	;END WITH CRLF

		;TABLE OF NAMES OF MONTHS (FIRST THREE LETTERS, IN SIXBIT)

NMNTBL:	MNIRP [SIXBIT /M/]

		;TABLE OF SIXBIT NAMES FOR DAYS OF THE WEEK
		;(THE "DAY" ON THE END LEFT OFF)

DOWTBL:	IRPS D,,[SUN MON TUES WEDNES THURS FRI SATUR]
	SIXBIT /D/
	TERMIN
IFN .-DOWTBL-7,.ERR BARF AT DOWTBL

SUBTTL NETWORK UP/DOWN

SYSNET:
IFE IMPP,JRST SCOR
IFN IMPP,[
	MOVEI I,[ASCIZ /IMP CRASHED, STATUS=/]
	PUSHJ P,SYSSP		;Print string
	MOVE A,IMERCN		;Get IMP error code
	PUSHJ P,SYSFWP		;Print that
	PUSHJ P,SYSTCR		;Time, CRLF
	SETOM IMERCN		;Reset error status
	MOVE A,LNETIM		;Last time net was initted
	SUB A,TIME		;A will be positive if net was last
	ADDI A,30.*30.		; initted less than 30 sec ago.
	PUSH P,A		;Flag for SYSNT5. + means don't restart IMP
	MOVNI A,2		;Say we are coming up, but no PI action yet,
	MOVEM A,IMPUP		; and prevent new net openers.  IMPUP may
	PUSHJ P,SYSNT5		; not already be -1 if got here via LOCK/NET
	JRST SCOR		;Reset net, then back to main loop

;Reset net, and potentially restart IMP
; Try restarting if IMP ready and -1(P) is negative. 
;
;IMPUP is -1 so no new opens can happen.

SYSNT5:	
	;PCLSR those users running in OPEN.
	;
	MOVEI U,0
IFN NCPP,[
	PUSHJ P,LSTSTP		;PCLSR all users in .OPEN
	    NETLST
	MOVSI I,-IMPSTL
SYSNT2:	SKIPL A,IMSOC1(I)
	 JRST SYSNT1
	HRRZS A
	SKIPN UNAME(A)
	 JRST SYSNT1
	MOVE T,APRC(A)
	TLNE T,BULGO		;Tree is being deleted anyway.
	 JRST SYSNT1
	PUSHJ P,IFSTOP		;Stop network user
	PUSHJ P,CHSCAA
	    PUSHJ P,SYSNT3	;Hack IOCHNM words of net user
SYSNT1:	AOBJN I,SYSNT2
];NCPP

	;Disconnect all STYs from the network
	;
	MOVEI I,NFSTTY+NSTTYS-1
SYSNT6:
	PUSHJ P,NSTYN0
	 JFCL
	CAILE I,NFSTTY
	 SOJA I,SYSNT6

IFN NCPP,[
	;Clean up connections which were closing
	;
	CONO PI,UTCOFF
	MOVSI I,-IMPSTL
SYSNT7:	SKIPL H,IMSOC1(I)
	 JRST SYSNT4
	PUSHJ P,IMPBRT	;RETURN BUFFER
	TLNN H,200000	;IN PROCESS OF CLOSING?
	 JRST SYSNT4	;NO, IGNORE
	SETZM IMSOC1(I)	;FLUSH SOCKET
	SOS IMNCS	;DECREASE COUNT OF CLOSES IN PROCESS
SYSNT4:	AOBJN I,SYSNT7	;LOOP THRU ALL SOCKETS
	SKIPE IMNCS	;SKIP IF 0 MORE CLOSES
	 BUG PAUSE,DEC,IMNCS,[NET CHANNELS NOT CLOSED YET]
	CONO PI,UTCON
];NCPP

	;Maybe try to bring the IMP up again
	;
	MOVEI U,0
	SKIPG -1(P)		;If last time down was < half minute ago,
	 CALL IMPCKR		; or IMP ready line is not set,
	  JRST LSWCLR		; then don't try to bring it up again
	PUSHJ P,IMPINI
IFN NCPP,PUSHJ P,LSWCLR		;Restart old network users
	PUSHJ P,WARMTTY
	MOVEI I,[ASCIZ /IMP up again./]
	JRST SYSSTD		;Print and return

IFN NCPP,[
SYSNT3:	HRRZ C,(R)
	CAIL C,NETDUI
	 CAILE C,NETDBO
	  POPJ P,	;NOT A NETWORK CHANNEL
	HLRE C,(R)	;SOCKET MAP INDEX
	JUMPL C,CPOPJ
	HRROS (R)	;SET LH OF IOCHNM TO -1
	HRRZ C,R
	SUBI C,IOCHNM(A)
	CAIL C,20
	 POPJ P,	;ON IOPDL
	MOVE C,CHNBIT(C)
	AND C,MSKST2(A)
	IORM C,IFPIR(A)	;INTERRUPT USER
	POPJ P,
];NCPP
];IMPP

;Try to bring IMP up if desirable
SYSIMU:
IFE IMPP,POPJ P,		;No IMP, no work
IFN IMPP,[
	SKIPGE IMPTCU		;Already trying to come up?
	  POPJ P,		;Yes, no meddling needed
	CALL IMPCKR		;Check if IMP ready line is now 
	 JRST [	SETZM IMPTCU	;IMP not ready, we are down and not trying
		POPJ P, ]	; to come up. Give up now
	PUSH P,[-1]		;Force SYSNT5 to try and restart IMP if called
	SKIPGE IMPUP		;Do this only if imp is temporarily down.
	 PUSHJ P,SYSNT5		;Reset world, restart IMP
	JRST POP1J		;Clean up and exit
];IMPP

;	PUSHJ P,LSTSTP
;	 LIST		;WHERE LIST/ <HEAD OF A LIST OF JOBS>
;STOPS ALL JOBS ON THE LIST, AND PUT THEM ON OUR LSWPR.
;LIST SHOULD BE LINKED THROUGH THE RH, AND EACH WORD IN THE LIST SHOULD BE
;IN THE USER VAR BLOCK OF SOME JOB. THAT JOB IS CONSIDERED TO BE ON THE LIST.
;0 IN THE RH MEANS NIL.
LSTSTP:	MOVE T,@(P)	;POINTER TO FIRST ELEMENT OF LIST
	CONO PI,CLKOFF
	MOVE T,(T)
LSTST1:	HRRZS T
	SKIPN A,T	;ADDRESS OF LSWB BLOCK
	JRST CLKOJ1
	MOVEI A,-USRSTG(A)
	IDIVI A,LUBLK
	IMULI A,LUBLK	;USER INDEX
	PUSH P,(T)
	PUSHJ P,IFSTOP	;STOP USER, ADDING HIS USTP TO OUR LSWPR
	POP P,T
	JRST LSTST1
SUBTTL SYSTEM JOB TYPE-OUT ROUTINES

;PRINT "<A>/	<@D>	<C>" IN OCTAL.
;USED BY SYSSET. CLOBBERS A,B,T.
SYSSCT:	HRRZS A
	PUSHJ P,SYSOPT
	MOVEI T,"/
	PUSHJ P,STYO
	PUSHJ P,STYOT	;TAB
	MOVE A,(D)	;GET CURRENT VALUE
	PUSHJ P,SYSFWP
	PUSHJ P,STYOT
	MOVE A,C	;GET NEW VALUE
	JRST SYSFWP

;STRING <- I, SPACE, TIME AND CRLF.
;CLOBBERS A THRU E AND T.
SYSSTD:	PUSHJ P,SYSSP

;SPACE, TIME AND CRLF.
;CLOBBERS A THRU E AND T.
SYSTCR:	PUSHJ P,SYSTPT

;TYPE A CRLF. CLOBBERS T.
SYSCRF:	SOS CTLCNT	;Countdown number of lines printed.
	MOVEI T,15
	PUSHJ P,STYO
	MOVEI T,12
	JRST STYO

SYSTPT:	PUSHJ P,STYOS	;TYPE SPACE, TIME
	CONSZ PI,200	;IF IN BUGDD0, MUSTN'T CALL GLPDTM
	 PUSHJ P,GLPDTM
	  POPJ P,	;TIME NOT KNOWN
	IDIVI A,SPD
	PUSHJ P,RTIME	;CONVERT TO SIXBIT.
	MOVE B,A	;DROP INTO SYSTCD

SYSTCD:	LDB A,[301400,,B]
	PUSHJ P,SYSTWR
	LDB A,[141400,,B]
	PUSHJ P,SYSTWR
	MOVE I,[140600,,B]
	JRST SYSIX2

;PREPARE FOR TYPING OUT A MESSAGE ON THE CONSOLE TTY. CALL HERE BEFORE
;STARTING TO TYPE A LINE, IF THERE IS A CHANCE THAT SYS JOB MIGHT JUST
;BE STARTING TO TYPE AFTER A PERIOD OF SILENCE.
WARMTTY:PUSHJ P,SYSCOP		;GET SYSTEM TTY READY TO USE
	.IOT STYOC,[^P]		;ADVANCE TO FRESH LINE
	.IOT STYOC,["A]
WARMT2:
IFN 1,	POPJ P,
.ELSE [	MOVE T,SYSCN
	MOVE T,TTLTM(T)	;DON'T DO THIS IF THERE'S BEEN ACTIVITY IN 2 MINUTES.
	ADDI T,115.*30.
	CAML T,TIME
	 POPJ P,
	PUSH P,[[MOVEI T,^H
		JRST WARMT1]]
	SKIPA T,[175]	;WARM UP TELETYPE (ONLY ON AI-KA FOR NOW)
];END .ELSE
DINGTTY:	SKIPA T,[^G]	;DING DING
WARMT1:	PUSHJ P,.+1
	PUSHJ P,.+1
	JRST STYO

;ROUTINE TO "OPEN" A CHANNEL TO THE SYSTEM CONSOLE
;IT'S DONE THIS WAY SO THAT THE CONSOLE CAN STILL BE
;USED AS A USER CONSOLE WHEN NECESSARY.  SYSTEM JOB
;MESSAGES WILL JUST COME OUT FROM TIME TO TIME.

SYSCOP:	HRLZ T,SYSCN		;FAKE UP AN IOCHNM WORD
	ADD T,[%TJDIS+%TJMOR,,TYODN]
	SKIPGE SYSCN
	 MOVEI T,NLODN		;IF NO SYS TTY AVAIL, USE NUL DEVICE
	MOVEM T,IOCHNM+STYOC
	POPJ P,

;TYPE OUT THE SIXBIT WORD IN B, QUIT WHEN WHAT IS LEFT IS BLANK
SYS6:	JUMPE B,CPOPJ	;RETURN WHEN NOTHING LEFT
	MOVEI A,0	;INITIALIZE FOR LSH
	LSHC A,6	;SHIFT A CHARACTER IN
	MOVEI T,40(A)	;CONVERT TO SIXBIT AND GET IN T
	PUSHJ P,STYO	;TYPE OUT THE CHARACTER
	JRST SYS6	;LOOP BACK FOR NEXT CHARACTER

;PRINT A MESSAGE ON ALL FREE CONSOLES. 40 SET IN LH(I) => IT IS ADDR OF ROUTINE;
;ELSE IT IS ADDR OF AN ASCIZ STRING TO BE TYPED FOLLOWED BY THE TIME AND A CRLF.
SYALCP:	TLNN I,40
	 HRLI I,440700	;SYSTEM ALL CONSOLES PRINT
	MOVEI A,0
SYALC1:	PUSHJ P,SYSTSU
	 AOJA A,SYALC3
	TLNE I,40
	 JRST SYALC5
	MOVE Q,I	;SO NOT TO MUNG I UNTIL END
SYALC2:	ILDB E,Q
	JUMPE E,SYALC4	;JUMP IF DONE
	.IOT STYOC,E	;COPY CHARACTER
	JRST SYALC2	;GO GET NEXT CHARACTER

SYALC5:	PUSH P,I
	PUSH P,A
	PUSHJ P,(I)
	POP P,A
	POP P,I
SYALC6:	MOVSI E,%TACFM
	IORM E,TTYSTA(A)	;DONT NEED CONSOLE FREE MSG ANY MORE
	AOS A		;INCREMENT CONSOLE NUMBER
SYALC3:	CAIGE A,NCT+IFN N11TYS,[1-N11TYS]	;IF MORE CONSOLES LEFT,
	 JRST SYALC1	;THEN PRINT OUT ON NEXT ONE
	JRST SYSCOP	;FINALLY RE-OPEN SYSTEM CONSOLE.

SYALC4:	PUSH P,[SYALC6]	;PUT TIME AT END OF MESSAGE
	PUSH P,A	;IF WE KNOW WHAT TIME IT IS
	PUSH P,B
	PUSHJ P,GLPDTM
	 JRST POPBAJ
	PUSH P,I
	IRPC A,,[ AT]
	.IOT STYOC,["A]	;PUT TIME IN UP/DOWN MESSAGES
	TERMIN
	PUSHJ P,SYSTPT
	POP P,I
	JRST POPBAJ

SYSTSU:	CONO PI,TTYOFF
	MOVE T,TTYSTA(A)
	TLZN T,%TACFM
	 JRST TTYONJ	;IN USE OR WILL GET CONSOLE FREE MSG => DON'T HACK IT
	MOVEM T,TTYSTA(A)
	CONO PI,TTYON
	AOS (P)		;TTY NEEDS HACKING, SO SKIP.
	HRLZ T,A
	ADD T,[%TJDIS+%TJMOR,,TYODN]
	MOVEM T,IOCHNM+STYOC	;"OPEN" THE CHANNEL.
SYSTS1:	MOVE T,TTYOPT(A)
	TLNN T,%TOIML
	 TLNN T,%TOMVU
	  POPJ P,	;IMLAC OR PRINTING TTY, DON'T CLEAR.
	MOVEI T,^P
	PUSHJ P,STYO
	MOVEI T,"C
	JRST STYO

	;SYSTEM JOB RADIX PRINT-OUT ROUTINES
	;FULL WORD (TWO HALFWORD) OCTAL:
SYSFWP:	TLNN A,-1	;IF LH=0,
	 JRST SYSOPT	;THEN PRINT ONLY RH
	LSHC A,-18.
	HLLM B,(P)
	PUSHJ P,SYSOPT
	HLRZ A,(P)
	MOVEI T,",	;",," BETWEEN HALFWORDS
	PUSHJ P,STYO
	PUSHJ P,STYO

	;OCTAL PRINTOUT, NO LEADING ZEROS, HALFWORD MAXIMUM
SYSOPT:	IDIVI A,10
	JUMPE A,SYSRP1
	HRLM B,(P)
	PUSHJ P,SYSOPT
SYSRP2:	HLRZ B,(P)	;ENTRY POINT FROM DECIMAL TYPEOUT ROUTINE
SYSRP1:	MOVEI T,"0(B)	;" " "
	JRST STYO

	;DECIMAL PRINTOUT, COMMAS EVERY 3 DIGITS, FULLWORD MAXIMUM
SYSDPC:	MOVE 0,A	;ROUTINE EXPECTS ARGUMENT IN A, CLOBBERS 0, A(=0+1), B(=A+1)
SYSDP5:	IDIVI 0,1000.	;GET LEAST SIGNIFICANT 3 DIGITS IN A
	JUMPE 0,SYSDPT	;PRINT HIGH ORDER DIGITS WITHOUT LEADING ZEROES
	HRLM A,(P)
	PUSHJ P,SYSDP5
	HLRZ A,(P)
	MOVEI T,",	;SINCE 3*N DIGITS LEFT TO BE TYPED, N>0,
	PUSHJ P,STYO	;PRINT OUT A COMMA
	MOVEI T,3	;NUMBER OF DIGITS TO PRINT OUT
	;ROUTINE TO PRINT OUT AS MANY DECIMAL DIGITS AS SPECIFIED IN T
SYSLZP:	IDIVI A,10.
	SOJLE T,SYSRP1
	HRLM B,(P)
	PUSHJ P,SYSLZP
	JRST SYSRP2

;PRINT NUMBER IN A IN DECIMAL; CLOBBERS B, T.
SYSDPT:	IDIVI A,10.
	JUMPE A,SYSRP1
	HRLM B,(P)
	PUSHJ P,SYSDPT
	JRST SYSRP2

STYOQ:	MOVEI T,"?	;TYPE OUT "?"
	JRST STYO

STYOT:	SKIPA T,[11]	;TAB
STYOS:	MOVEI T,40	;TYPE OUT A SPACE
STYO:	CONSO PI,200	;PI ON?  (SYSTEM UP)
	 JRST STYO1
	.IOT STYOC,T
	POPJ P,

;TYPE OUT DIRECTLY WHILE SYSTEM IS NOT RUNNING
STYO1:	HRLM T,(P)
	CAIN T,15
	 SETZM T00POS
	AOS T,T00POS
	CAIL T,75.
	 PUSHJ P,SYSCRF
	HLRZ T,(P)
IFN KA10P,[
	CONSZ TTY,20
	 JRST .-1
	DATAO TTY,T
] ;KA10P
IFN KL10P,[
	SETZM DTEFLG
	MOVEM T,DTECMD
	CONO DTE,%DBL11
	SKIPN DTEFLG
	 JRST .-1
] ;KL10P
IFN KS10P,[
	ANDI T,177		; ASCII for the 8080
	IORI T,400		; Means a character is present
	MOVEM T,8CTYOT
	CONI T
	IORI T,80INT
	CONO (T)		; punch 8080
	SKIPE 8CTYOT		; wait for completion
	 JRST .-1
	HLRZ T,(P)		; God knows who might look at T...
] ;KS10P
	POPJ P,

;PRINT WORD IN I AS 12. OCTAL DIGITS. CLOBBERS J,T.
SYSP:	MOVE J,[440300,,I]
	MOVE I,T
SYSP1:	ILDB T,J
	ADDI T,"0
	PUSHJ P,STYO
	TLNE J,770000
	JRST SYSP1
	POPJ P,

SYSSP:	HRLI I,440700	;ENTRY TO TYPE C(I) AS A POINTER TO ASCIZ
SYSSP2:	ILDB T,I
	JUMPE T,CPOPJ
	PUSHJ P,STYO
	JRST SYSSP2

SYSTWR:	LSH A,30-18.
	ADDI A,(SIXBIT /  :/)
	MOVE I,[220600,,A]
	JRST SYSIX2
SYSSIX:	PUSHJ P,STYOS	;TYPE A SPACE AND FALL IN
SYSIXP:	MOVE I,[440600,,A]	;ENTRY TO TYPE OUT C(A) AS SIXBIT
SYSIX2:	ILDB T,I
	ADDI T,40
	PUSHJ P,STYO
	TLNN I,770000
	POPJ P,
	JRST SYSIX2
